From c3bf92bd87b770fd81631a3853f7f5bb1ac6a4e8 Mon Sep 17 00:00:00 2001 From: yfr Date: Fri, 18 Jun 2004 08:34:31 +0000 Subject: [PATCH] DCQ : Merge with Ecole_Ete_a6. --- ChangeLog | 36 +- INSTALL | 8 +- Makefile.in | 17 +- adm_local/unix/config_files/check_Geom.m4 | 2 +- adm_local/unix/config_files/check_Med.m4 | 2 +- adm_local/unix/make_commence.in | 20 +- bin/VERSION | 2 +- configure.in.base | 27 +- cvs-tags | 18 - doc/Makefile.in | 11 +- doc/html/INPUT/doxyfile | 2 +- doc/html/INPUT/sources/static/tree.js | 2 +- doc/salome/AddNetgenInSalome2.pdf | Bin 0 -> 70678 bytes doc/salome/AddNetgenInSalome2.ps | 13935 ++++++++++++++++ doc/salome/AddNetgenInSalome2.sxw | Bin 0 -> 13363 bytes doc/salome/Makefile.in | 44 + doc/salome/PluginMeshers.txt | 188 + doc/salome/SMESH_index.html | 95 + doc/salome/gui/Makefile.in | 33 + idl/Makefile.in | 23 +- idl/SMESH_BasicHypothesis.idl | 101 +- idl/SMESH_Filter.idl | 110 + idl/SMESH_Gen.idl | 74 +- idl/SMESH_Group.idl | 103 + idl/SMESH_Hypothesis.idl | 17 +- idl/SMESH_Mesh.idl | 126 +- idl/SMESH_NetgenAlgorithm.idl | 45 + resources/SMESH.config | 2 + resources/SMESH_Meshers.xml | 78 + resources/SMESH_MeshersWithNETGEN.xml | 89 + resources/SMESH_en.xml | 270 +- resources/SMESH_fr.xml | 46 +- resources/StdMeshers.xml | 78 + resources/mesh_edit_group.png | Bin 0 -> 543 bytes resources/mesh_free_edges.png | Bin 0 -> 489 bytes resources/mesh_make_group.png | Bin 0 -> 432 bytes resources/mesh_multi_edges.png | Bin 0 -> 480 bytes resources/mesh_points.png | Bin 0 -> 499 bytes resources/mesh_tree_group.png | Bin 0 -> 411 bytes resources/mesh_tree_importedmesh.png | Bin 0 -> 912 bytes src/Controls/Makefile.in | 50 + src/Controls/SMESHControls.cxx | 42 + src/Controls/SMESH_Controls.cxx | 774 + src/Controls/SMESH_Controls.hxx | 340 + src/Driver/Document_Reader.cxx | 13 - src/Driver/Document_Reader.h | 9 +- src/Driver/Document_Writer.cxx | 32 +- src/Driver/Document_Writer.h | 8 +- src/Driver/Driver_Document.cxx | 36 + src/Driver/Driver_Document.h | 44 + src/Driver/Driver_Mesh.cxx | 46 + src/Driver/Driver_Mesh.h | 57 + src/Driver/Driver_SMDS_Mesh.cxx | 31 + src/Driver/Driver_SMDS_Mesh.h | 38 + src/Driver/Driver_SMESHDS_Mesh.cxx | 31 + src/Driver/Driver_SMESHDS_Mesh.h | 38 + src/Driver/Makefile.in | 16 +- src/Driver/SMESHDriver.cxx | 185 +- src/Driver/SMESHDriver.h | 15 +- src/DriverDAT/DAT_Test.cxx | 28 + src/DriverDAT/DriverDAT_R_SMDS_Mesh.cxx | 14 +- src/DriverDAT/DriverDAT_W_SMDS_Mesh.cxx | 62 +- src/DriverDAT/DriverDAT_W_SMESHDS_Mesh.cxx | 20 +- src/DriverDAT/Makefile.in | 18 +- src/DriverMED/DriverMED_Family.cxx | 367 + src/DriverMED/DriverMED_Family.h | 121 + .../DriverMED_R_SMESHDS_Document.cxx | 5 +- src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx | 1126 +- src/DriverMED/DriverMED_R_SMESHDS_Mesh.h | 56 +- src/DriverMED/DriverMED_W_SMDS_Mesh.cxx | 9 +- src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx | 1080 +- src/DriverMED/DriverMED_W_SMESHDS_Mesh.h | 60 +- src/DriverMED/MED_Test.cxx | 28 + src/DriverMED/Makefile.in | 26 +- src/DriverUNV/DriverUNV_R_SMDS_Mesh.cxx | 14 - src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx | 41 +- src/DriverUNV/DriverUNV_W_SMESHDS_Mesh.cxx | 21 +- src/DriverUNV/Makefile.in | 21 +- src/DriverUNV/UNV2411_Structure.cxx | 123 + src/DriverUNV/UNV2411_Structure.hxx | 46 + src/DriverUNV/UNV2412_Structure.cxx | 202 + src/DriverUNV/UNV2412_Structure.hxx | 59 + src/DriverUNV/UNV_Test.cxx | 69 + src/DriverUNV/UNV_Utilities.cxx | 37 + src/DriverUNV/UNV_Utilities.hxx | 104 + src/Makefile.in | 13 +- src/NETGENPlugin/Makefile.in | 67 + src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx | 1064 ++ src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx | 43 + src/NETGENPlugin/NETGENPlugin_NETGEN_3D_i.cxx | 85 + src/NETGENPlugin/NETGENPlugin_NETGEN_3D_i.hxx | 58 + .../NETGENPlugin_i.cxx} | 56 +- src/NETGENPlugin/NETGENPlugin_icons.po | 20 + src/OBJECT/Makefile.in | 25 +- src/OBJECT/SMESH_Actor.cxx | 1598 +- src/OBJECT/SMESH_Actor.h | 239 +- src/OBJECT/SMESH_DeviceActor.cxx | 357 + src/OBJECT/SMESH_DeviceActor.h | 133 + src/OBJECT/SMESH_Object.cxx | 1037 ++ src/OBJECT/SMESH_Object.h | 207 + src/SMDS/Makefile.in | 2 +- src/SMDS/SMDS_EdgePosition.hxx | 1 - src/SMDS/SMDS_FaceOfEdges.cxx | 65 +- src/SMDS/SMDS_FaceOfEdges.hxx | 13 +- src/SMDS/SMDS_FaceOfNodes.cxx | 77 +- src/SMDS/SMDS_FaceOfNodes.hxx | 13 +- src/SMDS/SMDS_HexahedronOfNodes.cxx | 36 +- src/SMDS/SMDS_HexahedronOfNodes.hxx | 18 +- src/SMDS/SMDS_Iterator.hxx | 6 +- src/SMDS/SMDS_IteratorOfElements.cxx | 23 +- src/SMDS/SMDS_IteratorOfElements.hxx | 10 +- src/SMDS/SMDS_Mesh.cxx | 1597 +- src/SMDS/SMDS_Mesh.hxx | 464 +- src/SMDS/SMDS_MeshEdge.cxx | 63 +- src/SMDS/SMDS_MeshEdge.hxx | 7 +- src/SMDS/SMDS_MeshElement.cxx | 69 +- src/SMDS/SMDS_MeshElement.hxx | 13 +- src/SMDS/SMDS_MeshElementIDFactory.cxx | 24 + src/SMDS/SMDS_MeshElementIDFactory.hxx | 3 +- src/SMDS/SMDS_MeshGroup.cxx | 64 +- src/SMDS/SMDS_MeshGroup.hxx | 55 +- src/SMDS/SMDS_MeshIDFactory.cxx | 2 +- src/SMDS/SMDS_MeshNode.cxx | 158 +- src/SMDS/SMDS_MeshNode.hxx | 11 +- src/SMDS/SMDS_MeshObject.hxx | 3 +- src/SMDS/SMDS_Position.cxx | 4 - src/SMDS/SMDS_Position.hxx | 6 +- src/SMDS/SMDS_SpacePosition.cxx | 6 +- src/SMDS/SMDS_SpacePosition.hxx | 3 +- src/SMDS/SMDS_Tria3OfNodes.cxx | 66 +- src/SMDS/SMDS_Tria3OfNodes.hxx | 7 +- src/SMDS/SMDS_VertexPosition.hxx | 1 - src/SMDS/SMDS_VolumeOfFaces.cxx | 80 +- src/SMDS/SMDS_VolumeOfFaces.hxx | 29 +- src/SMDS/SMDS_VolumeOfNodes.cxx | 101 +- src/SMDS/SMDS_VolumeOfNodes.hxx | 48 +- src/SMESHDS/Makefile.in | 8 +- src/SMESHDS/SMESHDS_Command.hxx | 1 - src/SMESHDS/SMESHDS_CommandType.hxx | 3 +- src/SMESHDS/SMESHDS_Group.cxx | 129 + src/SMESHDS/SMESHDS_Group.hxx | 72 + src/SMESHDS/SMESHDS_Hypothesis.cxx | 4 - src/SMESHDS/SMESHDS_Hypothesis.hxx | 1 - src/SMESHDS/SMESHDS_Mesh.cxx | 447 +- src/SMESHDS/SMESHDS_Mesh.hxx | 245 +- src/SMESHDS/SMESHDS_Script.cxx | 10 +- src/SMESHDS/SMESHDS_Script.hxx | 1 - src/SMESHDS/SMESHDS_SubMesh.cxx | 27 +- src/SMESHDS/SMESHDS_SubMesh.hxx | 8 +- src/SMESHFiltersSelection/SMESH_Type.h | 3 +- .../SMESH_TypeFilter.cxx | 53 +- src/SMESHGUI/Makefile.in | 46 +- src/SMESHGUI/SMESHBin.cxx | 4 + src/SMESHGUI/SMESHGUI.cxx | 9061 ++++------ src/SMESHGUI/SMESHGUI.h | 137 +- src/SMESHGUI/SMESHGUI_AddEdgeDlg.cxx | 6 +- src/SMESHGUI/SMESHGUI_AddFaceDlg.cxx | 6 +- src/SMESHGUI/SMESHGUI_AddSubMeshDlg.cxx | 554 +- src/SMESHGUI/SMESHGUI_AddSubMeshDlg.h | 53 +- src/SMESHGUI/SMESHGUI_AddVolumeDlg.cxx | 6 +- src/SMESHGUI/SMESHGUI_CreateHypothesesDlg.cxx | 290 + src/SMESHGUI/SMESHGUI_CreateHypothesesDlg.h | 97 + .../SMESHGUI_DiagonalInversionDlg.cxx | 4 +- src/SMESHGUI/SMESHGUI_EditHypothesesDlg.cxx | 1004 +- src/SMESHGUI/SMESHGUI_EditHypothesesDlg.h | 87 +- src/SMESHGUI/SMESHGUI_Filter.cxx | 114 + src/SMESHGUI/SMESHGUI_Filter.h | 68 + src/SMESHGUI/SMESHGUI_FilterDlg.cxx | 1302 ++ src/SMESHGUI/SMESHGUI_FilterDlg.h | 195 + src/SMESHGUI/SMESHGUI_GroupDlg.cxx | 977 ++ src/SMESHGUI/SMESHGUI_GroupDlg.h | 132 + src/SMESHGUI/SMESHGUI_Hypotheses.h | 74 + src/SMESHGUI/SMESHGUI_InitMeshDlg.cxx | 418 +- src/SMESHGUI/SMESHGUI_InitMeshDlg.h | 49 +- src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx | 739 +- src/SMESHGUI/SMESHGUI_MeshInfosDlg.h | 92 +- src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx | 13 +- src/SMESHGUI/SMESHGUI_NodesDlg.cxx | 8 +- .../SMESHGUI_OrientationElementsDlg.cxx | 6 +- .../SMESHGUI_Preferences_ScalarBarDlg.cxx | 831 +- .../SMESHGUI_Preferences_ScalarBarDlg.h | 107 +- .../SMESHGUI_Preferences_SelectionDlg.cxx | 307 + .../SMESHGUI_Preferences_SelectionDlg.h | 97 + src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx | 6 +- src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx | 6 +- src/SMESHGUI/SMESHGUI_StudyAPI.cxx | 284 +- src/SMESHGUI/SMESHGUI_StudyAPI.h | 14 +- src/SMESHGUI/SMESHGUI_Swig.cxx | 28 +- src/SMESHGUI/SMESHGUI_TransparencyDlg.cxx | 224 +- src/SMESHGUI/SMESHGUI_TransparencyDlg.h | 42 +- src/SMESHGUI/SMESHGUI_XmlHandler.cxx | 187 + src/SMESHGUI/SMESHGUI_XmlHandler.h | 58 + src/SMESHGUI/SMESH_icons.po | 67 +- src/SMESHGUI/SMESH_msg_en.po | 536 +- src/SMESH_I/Makefile.in | 67 +- src/SMESH_I/SMESHEngine.cxx | 23 + src/SMESH_I/SMESH_1D_Algo_i.cxx | 34 +- src/SMESH_I/SMESH_1D_Algo_i.hxx | 21 +- src/SMESH_I/SMESH_2D_Algo_i.cxx | 34 +- src/SMESH_I/SMESH_2D_Algo_i.hxx | 21 +- src/SMESH_I/SMESH_3D_Algo_i.cxx | 34 +- src/SMESH_I/SMESH_3D_Algo_i.hxx | 21 +- src/SMESH_I/SMESH_Algo_i.cxx | 54 +- src/SMESH_I/SMESH_Algo_i.hxx | 22 +- src/SMESH_I/SMESH_Filter_i.cxx | 914 + src/SMESH_I/SMESH_Filter_i.hxx | 417 + src/SMESH_I/SMESH_Gen_i.cxx | 3973 +++-- src/SMESH_I/SMESH_Gen_i.hxx | 359 +- src/SMESH_I/SMESH_Group_i.cxx | 358 + src/SMESH_I/SMESH_Group_i.hxx | 82 + src/SMESH_I/SMESH_HypothesisFactory_i.cxx | 142 - src/SMESH_I/SMESH_Hypothesis_i.cxx | 117 +- src/SMESH_I/SMESH_Hypothesis_i.hxx | 69 +- src/SMESH_I/SMESH_MEDMesh_i.cxx | 24 +- src/SMESH_I/SMESH_MEDSupport_i.cxx | 6 +- src/SMESH_I/SMESH_MeshEditor_i.cxx | 10 +- src/SMESH_I/SMESH_Mesh_i.cxx | 1018 +- src/SMESH_I/SMESH_Mesh_i.hxx | 100 +- src/SMESH_I/SMESH_NETGEN_3D_i.cxx | 60 - src/SMESH_I/SMESH_NETGEN_3D_i.hxx | 36 - src/SMESH_I/SMESH_subMesh_i.cxx | 121 +- src/SMESH_I/SMESH_subMesh_i.hxx | 15 +- src/SMESH_I/SMESH_test.py | 26 +- src/SMESH_I/smeshpy.py | 11 +- src/SMESH_SWIG/Makefile.in | 15 +- src/SMESH_SWIG/SMESH_Partition1_tetra.py | 472 +- src/SMESH_SWIG/SMESH_box2_tetra.py | 114 +- src/SMESH_SWIG/SMESH_box3_tetra.py | 114 +- src/SMESH_SWIG/SMESH_box_tetra.py | 120 +- src/SMESH_SWIG/SMESH_controls.py | 227 + src/SMESH_SWIG/SMESH_fixation.py | 7 +- src/SMESH_SWIG/SMESH_fixation_hexa.py | 79 +- src/SMESH_SWIG/SMESH_fixation_tetra.py | 113 +- src/SMESH_SWIG/SMESH_flight_skin.py | 94 +- src/SMESH_SWIG/SMESH_freebord.py | 78 + src/SMESH_SWIG/SMESH_mechanic.py | 237 +- src/SMESH_SWIG/SMESH_mechanic_tetra.py | 122 +- src/SMESH_SWIG/SMESH_test0.py | 3 - src/SMESH_SWIG/SMESH_test1.py | 130 +- src/SMESH_SWIG/SMESH_test2.py | 4 +- src/SMESH_SWIG/SMESH_test3.py | 3 - src/SMESH_SWIG/SMESH_test4.py | 65 + src/SMESH_SWIG/SMESH_test5.py | 79 + src/SMESH_SWIG/batchmode_mefisto.py | 150 + src/SMESH_SWIG/batchmode_smesh.py | 211 +- src/StdMeshers/Makefile.in | 81 + src/StdMeshers/StdMeshers_Hexa_3D.cxx | 1004 ++ src/StdMeshers/StdMeshers_Hexa_3D.hxx | 140 + src/StdMeshers/StdMeshers_LengthFromEdges.cxx | 139 + src/StdMeshers/StdMeshers_LengthFromEdges.hxx | 57 + .../StdMeshers_LocalLength.cxx} | 106 +- src/StdMeshers/StdMeshers_LocalLength.hxx | 55 + src/StdMeshers/StdMeshers_MEFISTO_2D.cxx | 643 + src/StdMeshers/StdMeshers_MEFISTO_2D.hxx | 88 + src/StdMeshers/StdMeshers_MaxElementArea.cxx | 139 + src/StdMeshers/StdMeshers_MaxElementArea.hxx | 55 + .../StdMeshers_MaxElementVolume.cxx | 141 + .../StdMeshers_MaxElementVolume.hxx | 57 + .../StdMeshers_NotConformAllowed.cxx} | 68 +- .../StdMeshers_NotConformAllowed.hxx | 48 + .../StdMeshers_NumberOfSegments.cxx | 171 + .../StdMeshers_NumberOfSegments.hxx | 63 + src/StdMeshers/StdMeshers_Quadrangle_2D.cxx | 644 + src/StdMeshers/StdMeshers_Quadrangle_2D.hxx | 102 + src/StdMeshers/StdMeshers_Regular_1D.cxx | 331 + src/StdMeshers/StdMeshers_Regular_1D.hxx | 65 + src/StdMeshersGUI/Makefile.in | 78 + src/StdMeshersGUI/StdMeshersGUI.cxx | 225 + .../StdMeshersGUI_LocalLengthDlg.cxx | 289 + .../StdMeshersGUI_LocalLengthDlg.h | 89 + .../StdMeshersGUI_MaxElementAreaDlg.cxx | 291 + .../StdMeshersGUI_MaxElementAreaDlg.h | 89 + .../StdMeshersGUI_MaxElementVolumeDlg.cxx | 290 + .../StdMeshersGUI_MaxElementVolumeDlg.h | 89 + .../StdMeshersGUI_NbSegmentsDlg.cxx | 289 + .../StdMeshersGUI_NbSegmentsDlg.h | 89 + src/StdMeshersGUI/StdMeshers_icons.po | 81 + src/StdMeshersGUI/StdMeshers_msg_en.po | 49 + src/StdMeshers_I/Makefile.in | 76 + .../StdMeshers_Hexa_3D_i.cxx} | 52 +- .../StdMeshers_Hexa_3D_i.hxx} | 31 +- .../StdMeshers_LengthFromEdges_i.cxx} | 87 +- .../StdMeshers_LengthFromEdges_i.hxx} | 36 +- .../StdMeshers_LocalLength_i.cxx} | 88 +- src/StdMeshers_I/StdMeshers_LocalLength_i.hxx | 67 + .../StdMeshers_MEFISTO_2D_i.cxx} | 53 +- .../StdMeshers_MEFISTO_2D_i.hxx} | 35 +- .../StdMeshers_MaxElementArea_i.cxx | 119 + .../StdMeshers_MaxElementArea_i.hxx} | 36 +- .../StdMeshers_MaxElementVolume_i.cxx | 120 + .../StdMeshers_MaxElementVolume_i.hxx} | 34 +- .../StdMeshers_NotConformAllowed_i.cxx} | 48 +- .../StdMeshers_NotConformAllowed_i.hxx} | 29 +- .../StdMeshers_NumberOfSegments_i.cxx | 157 + .../StdMeshers_NumberOfSegments_i.hxx} | 43 +- .../StdMeshers_Quadrangle_2D_i.cxx} | 52 +- .../StdMeshers_Quadrangle_2D_i.hxx} | 31 +- .../StdMeshers_Regular_1D_i.cxx} | 69 +- .../StdMeshers_Regular_1D_i.hxx} | 34 +- src/StdMeshers_I/StdMeshers_i.cxx | 86 + 300 files changed, 50711 insertions(+), 16107 deletions(-) create mode 100644 doc/salome/AddNetgenInSalome2.pdf create mode 100644 doc/salome/AddNetgenInSalome2.ps create mode 100644 doc/salome/AddNetgenInSalome2.sxw create mode 100644 doc/salome/Makefile.in create mode 100644 doc/salome/PluginMeshers.txt create mode 100644 doc/salome/SMESH_index.html create mode 100644 doc/salome/gui/Makefile.in create mode 100644 idl/SMESH_Filter.idl create mode 100644 idl/SMESH_Group.idl create mode 100644 idl/SMESH_NetgenAlgorithm.idl create mode 100644 resources/SMESH.config create mode 100644 resources/SMESH_Meshers.xml create mode 100644 resources/SMESH_MeshersWithNETGEN.xml create mode 100644 resources/StdMeshers.xml create mode 100644 resources/mesh_edit_group.png create mode 100755 resources/mesh_free_edges.png create mode 100644 resources/mesh_make_group.png create mode 100755 resources/mesh_multi_edges.png create mode 100644 resources/mesh_points.png create mode 100644 resources/mesh_tree_group.png create mode 100644 resources/mesh_tree_importedmesh.png create mode 100644 src/Controls/Makefile.in create mode 100644 src/Controls/SMESHControls.cxx create mode 100644 src/Controls/SMESH_Controls.cxx create mode 100644 src/Controls/SMESH_Controls.hxx create mode 100644 src/Driver/Driver_Document.cxx create mode 100644 src/Driver/Driver_Document.h create mode 100644 src/Driver/Driver_Mesh.cxx create mode 100644 src/Driver/Driver_Mesh.h create mode 100644 src/Driver/Driver_SMDS_Mesh.cxx create mode 100644 src/Driver/Driver_SMDS_Mesh.h create mode 100644 src/Driver/Driver_SMESHDS_Mesh.cxx create mode 100644 src/Driver/Driver_SMESHDS_Mesh.h create mode 100644 src/DriverDAT/DAT_Test.cxx create mode 100644 src/DriverMED/DriverMED_Family.cxx create mode 100644 src/DriverMED/DriverMED_Family.h create mode 100644 src/DriverMED/MED_Test.cxx create mode 100644 src/DriverUNV/UNV2411_Structure.cxx create mode 100644 src/DriverUNV/UNV2411_Structure.hxx create mode 100644 src/DriverUNV/UNV2412_Structure.cxx create mode 100644 src/DriverUNV/UNV2412_Structure.hxx create mode 100644 src/DriverUNV/UNV_Test.cxx create mode 100644 src/DriverUNV/UNV_Utilities.cxx create mode 100644 src/DriverUNV/UNV_Utilities.hxx create mode 100644 src/NETGENPlugin/Makefile.in create mode 100644 src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx create mode 100644 src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx create mode 100644 src/NETGENPlugin/NETGENPlugin_NETGEN_3D_i.cxx create mode 100644 src/NETGENPlugin/NETGENPlugin_NETGEN_3D_i.hxx rename src/{SMESH_I/SMESH_HypothesisFactory_i.hxx => NETGENPlugin/NETGENPlugin_i.cxx} (57%) create mode 100644 src/NETGENPlugin/NETGENPlugin_icons.po create mode 100644 src/OBJECT/SMESH_DeviceActor.cxx create mode 100644 src/OBJECT/SMESH_DeviceActor.h create mode 100644 src/OBJECT/SMESH_Object.cxx create mode 100644 src/OBJECT/SMESH_Object.h create mode 100644 src/SMESHDS/SMESHDS_Group.cxx create mode 100644 src/SMESHDS/SMESHDS_Group.hxx create mode 100644 src/SMESHGUI/SMESHBin.cxx create mode 100644 src/SMESHGUI/SMESHGUI_CreateHypothesesDlg.cxx create mode 100644 src/SMESHGUI/SMESHGUI_CreateHypothesesDlg.h create mode 100755 src/SMESHGUI/SMESHGUI_Filter.cxx create mode 100755 src/SMESHGUI/SMESHGUI_Filter.h create mode 100755 src/SMESHGUI/SMESHGUI_FilterDlg.cxx create mode 100755 src/SMESHGUI/SMESHGUI_FilterDlg.h create mode 100644 src/SMESHGUI/SMESHGUI_GroupDlg.cxx create mode 100644 src/SMESHGUI/SMESHGUI_GroupDlg.h create mode 100644 src/SMESHGUI/SMESHGUI_Hypotheses.h create mode 100644 src/SMESHGUI/SMESHGUI_Preferences_SelectionDlg.cxx create mode 100644 src/SMESHGUI/SMESHGUI_Preferences_SelectionDlg.h create mode 100644 src/SMESHGUI/SMESHGUI_XmlHandler.cxx create mode 100644 src/SMESHGUI/SMESHGUI_XmlHandler.h create mode 100644 src/SMESH_I/SMESHEngine.cxx create mode 100644 src/SMESH_I/SMESH_Filter_i.cxx create mode 100644 src/SMESH_I/SMESH_Filter_i.hxx create mode 100644 src/SMESH_I/SMESH_Group_i.cxx create mode 100644 src/SMESH_I/SMESH_Group_i.hxx delete mode 100644 src/SMESH_I/SMESH_HypothesisFactory_i.cxx delete mode 100644 src/SMESH_I/SMESH_NETGEN_3D_i.cxx delete mode 100644 src/SMESH_I/SMESH_NETGEN_3D_i.hxx create mode 100644 src/SMESH_SWIG/SMESH_controls.py create mode 100644 src/SMESH_SWIG/SMESH_freebord.py create mode 100755 src/SMESH_SWIG/SMESH_test4.py create mode 100644 src/SMESH_SWIG/SMESH_test5.py create mode 100644 src/SMESH_SWIG/batchmode_mefisto.py create mode 100644 src/StdMeshers/Makefile.in create mode 100644 src/StdMeshers/StdMeshers_Hexa_3D.cxx create mode 100644 src/StdMeshers/StdMeshers_Hexa_3D.hxx create mode 100644 src/StdMeshers/StdMeshers_LengthFromEdges.cxx create mode 100644 src/StdMeshers/StdMeshers_LengthFromEdges.hxx rename src/{SMESH_I/SMESH_NumberOfSegments_i.cxx => StdMeshers/StdMeshers_LocalLength.cxx} (55%) create mode 100644 src/StdMeshers/StdMeshers_LocalLength.hxx create mode 100644 src/StdMeshers/StdMeshers_MEFISTO_2D.cxx create mode 100644 src/StdMeshers/StdMeshers_MEFISTO_2D.hxx create mode 100644 src/StdMeshers/StdMeshers_MaxElementArea.cxx create mode 100644 src/StdMeshers/StdMeshers_MaxElementArea.hxx create mode 100644 src/StdMeshers/StdMeshers_MaxElementVolume.cxx create mode 100644 src/StdMeshers/StdMeshers_MaxElementVolume.hxx rename src/{SMESH_I/SMESH_MaxElementArea_i.cxx => StdMeshers/StdMeshers_NotConformAllowed.cxx} (61%) create mode 100644 src/StdMeshers/StdMeshers_NotConformAllowed.hxx create mode 100644 src/StdMeshers/StdMeshers_NumberOfSegments.cxx create mode 100644 src/StdMeshers/StdMeshers_NumberOfSegments.hxx create mode 100644 src/StdMeshers/StdMeshers_Quadrangle_2D.cxx create mode 100644 src/StdMeshers/StdMeshers_Quadrangle_2D.hxx create mode 100644 src/StdMeshers/StdMeshers_Regular_1D.cxx create mode 100644 src/StdMeshers/StdMeshers_Regular_1D.hxx create mode 100644 src/StdMeshersGUI/Makefile.in create mode 100644 src/StdMeshersGUI/StdMeshersGUI.cxx create mode 100644 src/StdMeshersGUI/StdMeshersGUI_LocalLengthDlg.cxx create mode 100644 src/StdMeshersGUI/StdMeshersGUI_LocalLengthDlg.h create mode 100644 src/StdMeshersGUI/StdMeshersGUI_MaxElementAreaDlg.cxx create mode 100644 src/StdMeshersGUI/StdMeshersGUI_MaxElementAreaDlg.h create mode 100644 src/StdMeshersGUI/StdMeshersGUI_MaxElementVolumeDlg.cxx create mode 100644 src/StdMeshersGUI/StdMeshersGUI_MaxElementVolumeDlg.h create mode 100644 src/StdMeshersGUI/StdMeshersGUI_NbSegmentsDlg.cxx create mode 100644 src/StdMeshersGUI/StdMeshersGUI_NbSegmentsDlg.h create mode 100644 src/StdMeshersGUI/StdMeshers_icons.po create mode 100644 src/StdMeshersGUI/StdMeshers_msg_en.po create mode 100644 src/StdMeshers_I/Makefile.in rename src/{SMESH_I/SMESH_Hexa_3D_i.cxx => StdMeshers_I/StdMeshers_Hexa_3D_i.cxx} (62%) rename src/{SMESH_I/SMESH_Hexa_3D_i.hxx => StdMeshers_I/StdMeshers_Hexa_3D_i.hxx} (65%) rename src/{SMESH_I/SMESH_LengthFromEdges_i.cxx => StdMeshers_I/StdMeshers_LengthFromEdges_i.cxx} (50%) rename src/{SMESH_I/SMESH_LengthFromEdges_i.hxx => StdMeshers_I/StdMeshers_LengthFromEdges_i.hxx} (60%) rename src/{SMESH_I/SMESH_MaxElementVolume_i.cxx => StdMeshers_I/StdMeshers_LocalLength_i.cxx} (50%) create mode 100644 src/StdMeshers_I/StdMeshers_LocalLength_i.hxx rename src/{SMESH_I/SMESH_Quadrangle_2D_i.cxx => StdMeshers_I/StdMeshers_MEFISTO_2D_i.cxx} (60%) rename src/{SMESH_I/SMESH_MEFISTO_2D_i.hxx => StdMeshers_I/StdMeshers_MEFISTO_2D_i.hxx} (60%) create mode 100644 src/StdMeshers_I/StdMeshers_MaxElementArea_i.cxx rename src/{SMESH_I/SMESH_MaxElementArea_i.hxx => StdMeshers_I/StdMeshers_MaxElementArea_i.hxx} (60%) create mode 100644 src/StdMeshers_I/StdMeshers_MaxElementVolume_i.cxx rename src/{SMESH_I/SMESH_MaxElementVolume_i.hxx => StdMeshers_I/StdMeshers_MaxElementVolume_i.hxx} (60%) rename src/{SMESH_I/SMESH_Regular_1D_i.cxx => StdMeshers_I/StdMeshers_NotConformAllowed_i.cxx} (58%) rename src/{SMESH_I/SMESH_LocalLength_i.hxx => StdMeshers_I/StdMeshers_NotConformAllowed_i.hxx} (66%) create mode 100644 src/StdMeshers_I/StdMeshers_NumberOfSegments_i.cxx rename src/{SMESH_I/SMESH_NumberOfSegments_i.hxx => StdMeshers_I/StdMeshers_NumberOfSegments_i.hxx} (56%) rename src/{SMESH_I/SMESH_MEFISTO_2D_i.cxx => StdMeshers_I/StdMeshers_Quadrangle_2D_i.cxx} (59%) rename src/{SMESH_I/SMESH_Quadrangle_2D_i.hxx => StdMeshers_I/StdMeshers_Quadrangle_2D_i.hxx} (63%) rename src/{SMESH_I/SMESH_LocalLength_i.cxx => StdMeshers_I/StdMeshers_Regular_1D_i.cxx} (60%) rename src/{SMESH_I/SMESH_Regular_1D_i.hxx => StdMeshers_I/StdMeshers_Regular_1D_i.hxx} (64%) create mode 100644 src/StdMeshers_I/StdMeshers_i.cxx diff --git a/ChangeLog b/ChangeLog index 099c4d874..46cf0c992 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,43 +1,9 @@ ############################################################################### #This is the SMESH change log. Do not modify because it is automatically #created with : -#cvs2cl.pl --accum -l "-b" -U users.cvs2cl --header header.cvs2cl -T -b --utc +#cvs2cl.pl -l "-b" -U users.cvs2cl --header header.cvs2cl -T -b --utc ############################################################################### -2004-03-23 13:25 tag V1_5_0 - -2004-03-23 13:20 Jerome Robert - - * INSTALL, bin/VERSION: Version 1.5.0. - -2004-03-23 09:53 Jerome Robert - - * src/SMESHGUI/SMESHGUI.cxx: Add a MEDFILE attribut for selection - in Efficas. Patch submited by P. Rascle on 2004-03-22. - * src/SMDS/SMDS_Position.cxx: Fix bug SMESH5512 (Crash on DEBIAN - woody, V1_4_0b). - -2004-03-16 12:51 Jerome Robert - - * src/SMESHGUI/SMESHGUI_Swig.cxx: Fix bug SMESH5451: SMESH_mechanic - script aborts. - * doc/html/SMESHTutorial_1/: ControlFeature.png, ImportResult.png, - MeshInit.png, MeshResult.png, MeshResult2.png, SMESHOverview.png, - SMESHTutorial_1.html, SelectAlgorithms.png, SetColor.png, - SubMeshContruction.png, SubShapesSelection.png: Add a small - tutorial. - -2004-03-15 18:42 Jerome Robert - - * Merge br_enable_import_mesh. Enable import mesh and save/load SMESH study. - -2004-02-02 16:43 Jerome Robert - - * src/SMDS/SMDS_Mesh.cxx: Fix a bug (crash when adding an - hexahedron from ids). - -2004-01-30 15:42 tag V1_4_0b - 2004-01-30 13:18 Nicolas Rejneri * doc/html/INPUT/: doxyfile, sources/static/tree.js: NRI : 1.4.0 diff --git a/INSTALL b/INSTALL index 096e2e4f7..694c906d4 100644 --- a/INSTALL +++ b/INSTALL @@ -1,6 +1,6 @@ -This is SMESH V1_5_0 +This is SMESH V2.0.0 Compatible with : - GEOM V1_4_0 - KERNEL V1_4_0 - MED V1_4_0 + GEOM V2_0_0 + KERNEL V2_0_0 + MED V2_0_0 diff --git a/Makefile.in b/Makefile.in index ac708eff5..a79be56d3 100644 --- a/Makefile.in +++ b/Makefile.in @@ -14,7 +14,7 @@ VPATH=.:@srcdir@:@top_srcdir@/bin:@top_srcdir@/resources:./bin:@top_srcdir@/idl @COMMENCE@ -SUBDIRS = idl src +SUBDIRS = idl src doc RESOURCES_FILES = \ delete.png \ @@ -40,6 +40,8 @@ mesh_hypo_volume.png \ mesh_info.png \ mesh_init.png \ mesh_length.png \ +mesh_free_edges.png \ +mesh_multi_edges.png \ mesh_line_n.png \ mesh_line.png \ mesh_move_node.png \ @@ -71,6 +73,7 @@ mesh_tree_hypo.png \ mesh_tree_hypo_segment.png \ mesh_tree_hypo_volume.png \ mesh_tree_mesh.png \ +mesh_tree_importedmesh.png \ mesh_tree_mesh_warn.png \ mesh_triangle_n.png \ mesh_triangle.png \ @@ -78,10 +81,16 @@ mesh_update.png \ mesh_vertex_n.png \ mesh_vertex.png \ mesh_wireframe.png \ +mesh_points.png \ mesh_wrap.png \ +mesh_tree_group.png \ +mesh_edit_group.png \ +mesh_make_group.png \ ModuleMesh.png \ select1.png \ SMESH_en.xml \ +SMESH.config \ +StdMeshers.xml \ SMESHCatalog.xml \ flight_solid.brep @@ -104,10 +113,10 @@ include/salome/SALOMEconfig.h: salome_adm/unix/SALOMEconfig.ref # test if SALOMEconfig.h has changed (contents) salome_adm/unix/SALOMEconfig.ref: salome_adm/unix/SALOMEconfig.h @if ! [ -a $@ ]; then \ - cp -p $< $@; \ + cp -p -f $< $@; \ fi; \ if ! cmp $< $@; then \ - cp -p $< $@; \ + cp -p -f $< $@; \ fi; \ include/salome/sstream: salome_adm/unix/sstream @@ -131,7 +140,7 @@ install-include: $(include_list) $(INSTALL) -d $(includedir) @for f in X $(include_list); do \ if test $$f != X; then \ - ($(INSTALL_DATA) $$f $(includedir)/. || exit 1); \ + ($(INSTALL_DATA) -p $$f $(includedir)/. || exit 1); \ fi; \ done diff --git a/adm_local/unix/config_files/check_Geom.m4 b/adm_local/unix/config_files/check_Geom.m4 index 947c44a12..803ca754b 100644 --- a/adm_local/unix/config_files/check_Geom.m4 +++ b/adm_local/unix/config_files/check_Geom.m4 @@ -47,7 +47,7 @@ if test -f ${GEOM_DIR}/bin/salome/libGEOM_Swig.py ; then else AC_MSG_WARN("Cannot find compiled Geom module distribution") fi - + AC_MSG_RESULT(for Geom: $Geom_ok) ])dnl diff --git a/adm_local/unix/config_files/check_Med.m4 b/adm_local/unix/config_files/check_Med.m4 index 839a3d7be..492727053 100644 --- a/adm_local/unix/config_files/check_Med.m4 +++ b/adm_local/unix/config_files/check_Med.m4 @@ -45,7 +45,7 @@ if test -f ${MED_DIR}/bin/salome/libMEDMEM_Swig.py ; then AC_SUBST(MED_ROOT_DIR) else - AC_MSG_WARN("Cannot find compiled Med module distribution") + AC_MSG_WARN("Cannot find Med module sources") fi AC_MSG_RESULT(for Med: $Med_ok) diff --git a/adm_local/unix/make_commence.in b/adm_local/unix/make_commence.in index a42b18798..ad1a9a52f 100644 --- a/adm_local/unix/make_commence.in +++ b/adm_local/unix/make_commence.in @@ -34,6 +34,10 @@ CXX = @CXX@ CXXFLAGS = @CXXFLAGS@ CXX_DEPEND_FLAG = @CXX_DEPEND_FLAG@ +# BOOST Library + +BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ + # JAVA JAVA_INCLUDES = @JAVA_INCLUDES@ @@ -127,7 +131,8 @@ OMNIORB_CXXFLAGS = @OMNIORB_CXXFLAGS@ OMNIORB_IDL = @OMNIORB_IDL@ OMNIORB_IDLCXXFLAGS = @OMNIORB_IDLCXXFLAGS@ -OMNIORB_IDLPYFLAGS = @OMNIORB_IDLPYFLAGS@ -I$(top_srcdir)/idl -I$(top_builddir)/idl -I$(KERNEL_ROOT_DIR)/idl/salome -I$(GEOM_ROOT_DIR)/idl/salome -I$(MED_ROOT_DIR)/idl/salome +OMNIORB_IDLPYFLAGS = @OMNIORB_IDLPYFLAGS@ -I$(top_srcdir)/idl -I$(top_builddir)/idl/salome \ + -I$(KERNEL_ROOT_DIR)/idl/salome -I$(GEOM_ROOT_DIR)/idl/salome -I$(MED_ROOT_DIR)/idl/salome OMNIORB_IDL_CLN_H = @OMNIORB_IDL_CLN_H@ OMNIORB_IDL_CLN_CXX = @OMNIORB_IDL_CLN_CXX@ @@ -144,7 +149,8 @@ CORBA_INCLUDES = @CORBA_INCLUDES@ CORBA_LIBS = @CORBA_LIBS@ CORBA_CXXFLAGS = @CORBA_CXXFLAGS@ -IDLCXXFLAGS = -bcxx @IDLCXXFLAGS@ -I$(top_srcdir)/idl -I$(top_builddir)/idl -I$(KERNEL_ROOT_DIR)/idl/salome -I$(GEOM_ROOT_DIR)/idl/salome -I$(MED_ROOT_DIR)/idl/salome +IDLCXXFLAGS = -bcxx @IDLCXXFLAGS@ -I$(top_srcdir)/idl -I$(top_builddir)/idl/salome \ + -I$(KERNEL_ROOT_DIR)/idl/salome -I$(GEOM_ROOT_DIR)/idl/salome -I$(MED_ROOT_DIR)/idl/salome IDLPYFLAGS = @IDLPYFLAGS@ IDL = @IDL@ @@ -195,13 +201,13 @@ datadir=@datadir@/salome idldir=$(prefix)/idl/salome sharedpydir=@libdir@/python$(PYTHON_VERSION)/site-packages/salome/shared_modules -docdir=$(datadir)/doc +docdir=${prefix}/doc/salome # # begin of package rules # -.PHONY: all lib bin inc resources tests install uninstall dep depend depend_idl cleandep mostlyclean clean distclean +.PHONY: all lib bin inc resources docs tests install uninstall dep depend depend_idl cleandep mostlyclean clean distclean .SUFFIXES: .cxx .cc .c .f .o .lo .idl .py .i .ui .po .qm @@ -243,11 +249,7 @@ ac_cxx_namespaces.m4 check_omniorb.m4 pyembed.m4 \ ac_cxx_partial_specialization.m4 check_opengl.m4 python.m4 \ ac_cxx_typename.m4 check_pthreads.m4 check_cas.m4 \ ac_cc_warnings.m4 check_qt.m4 check_med2.m4 \ -check_swig.m4 - -#ifeq (@WITHNETGEN@,yes) -# ACLOCAL_SRC += check_Netgen.m4 -#endif +check_swig.m4 check_boost.m4 $(top_srcdir)/aclocal.m4: $(ACLOCAL_SRC:%=@KERNEL_ROOT_DIR@/salome_adm/unix/config_files/%) cd $(top_srcdir) ; aclocal --acdir=adm_local/unix/config_files -I @KERNEL_ROOT_DIR@/salome_adm/unix/config_files diff --git a/bin/VERSION b/bin/VERSION index 8132f186c..fe67dd416 100755 --- a/bin/VERSION +++ b/bin/VERSION @@ -1,2 +1,2 @@ -THIS IS SALOME - SMESH VERSION: 1.5.0 +THIS IS SALOME - SMESH VERSION: 2.0.0 diff --git a/configure.in.base b/configure.in.base index f2e7919b0..5573498ca 100644 --- a/configure.in.base +++ b/configure.in.base @@ -113,6 +113,14 @@ dnl AC_CXX_HAVE_SSTREAM +echo +echo --------------------------------------------- +echo BOOST Library +echo --------------------------------------------- +echo + +CHECK_BOOST + dnl dnl --------------------------------------------- dnl testing MPICH @@ -273,14 +281,6 @@ echo CHECK_MED -echo -echo --------------------------------------------- -echo Testing Netgen -echo --------------------------------------------- -echo - -CHECK_NETGEN - echo echo --------------------------------------------- echo Summary @@ -288,7 +288,7 @@ echo --------------------------------------------- echo echo Configure -variables="cc_ok lex_yacc_ok python_ok swig_ok threads_ok OpenGL_ok qt_ok vtk_ok hdf5_ok med2_ok omniORB_ok occ_ok doxygen_ok graphviz_ok Kernel_ok Geom_ok Med_ok Netgen_ok" +variables="cc_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok OpenGL_ok qt_ok vtk_ok hdf5_ok med2_ok omniORB_ok occ_ok doxygen_ok graphviz_ok Kernel_ok Geom_ok Med_ok" for var in $variables do @@ -318,7 +318,7 @@ else fi # make other build directories -for rep in salome_adm adm_local doc bin/salome include/salome lib/salome share/salome/resources share/salome/doc idl +for rep in salome_adm adm_local doc bin/salome include/salome lib/salome share/salome/resources idl do # if test ! -d $rep ; then # eval mkdir $rep @@ -351,14 +351,15 @@ dnl copy shells and utilities contained in the bin directory dnl excluding .in files (treated in AC-OUTPUT below) and CVS dnl directory -cd bin +mkdir -p bin/salome +cd bin/salome for i in $ROOT_SRCDIR/bin/* do local_bin=`echo $i | sed -e "s,$ROOT_SRCDIR,.,"` case "$local_bin" in *.in | *~) ;; - ./bin/CVS) ;; - *) ln -fs $i; echo $local_bin ;; + ./bin/CVS | ./bin/salome) ;; + *) /usr/bin/install -C $i .; echo $local_bin ;; esac done cd $ROOT_BUILDDIR diff --git a/cvs-tags b/cvs-tags index 6db9a6ed9..6991d061f 100644 --- a/cvs-tags +++ b/cvs-tags @@ -33,21 +33,3 @@ V1_3_1: 2004-01-05 14:28 merge_1_2_d: 2003-01-20 11:25 Branch to merge Release 1.2d of Salome Pro. - -V1_4_0b: 2004-01-30 15:42 - Pre-release of 1.4.0. Include the merge of the branch merge_1_2_d. - -V1_4_0_branch: 2004-01-30 15:42 - Maintenance branch for 1.4.0. This tag is equal to V1_4_0b. - -br_enable_import_mesh: 2004-02-16 10:00 - Branch on head after V1_4_0b. Development branch enable import mesh and save/load SMESH study. Initiated by Jerome Robert. - -br_geomclient_colocal: 2004-02-23 10:00 - Branch on br_enable_import_mesh. Development branch for colocalization. Initiated by Francis KLOSS. - -V1_4_0: 2004-03-23 11:40 - Release 1.4.0. Tag on V1_4_0_branch branch. - -V1_5_0: 2004-03-23 13:25 - Release 1.5.0. Tag on head. Include mesh import/export, save/load study, tutorial, bug corrected in V1_4_0. diff --git a/doc/Makefile.in b/doc/Makefile.in index 019015971..7295ede75 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -11,9 +11,11 @@ top_builddir=.. srcdir=@srcdir@ VPATH=.:@srcdir@ -SUBDIRS=html +SUBDIRS= salome -doc: +@COMMENCE@ + +docs: @@SETX@; for d in $(SUBDIRS); do \ (cd $$d && $(MAKE) $@) || exit 1; \ done @@ -31,3 +33,8 @@ install: @@SETX@; for d in $(SUBDIRS); do \ (cd $$d && $(MAKE) $@) || exit 1; \ done + +uninstall: + @@SETX@; for d in $(SUBDIRS); do \ + (cd $$d && $(MAKE) $@) || exit 1; \ + done diff --git a/doc/html/INPUT/doxyfile b/doc/html/INPUT/doxyfile index d1850bc22..9e1e6eb0e 100755 --- a/doc/html/INPUT/doxyfile +++ b/doc/html/INPUT/doxyfile @@ -3,7 +3,7 @@ #--------------------------------------------------------------------------- # General configuration options #--------------------------------------------------------------------------- -PROJECT_NAME = "SALOME - SMESH - v.1.4.0" +PROJECT_NAME = "SALOME - SMESH - v.1.3.0" PROJECT_NUMBER = id#1.1 OUTPUT_DIRECTORY = ../ OUTPUT_LANGUAGE = English diff --git a/doc/html/INPUT/sources/static/tree.js b/doc/html/INPUT/sources/static/tree.js index c03d681b0..934d43f84 100755 --- a/doc/html/INPUT/sources/static/tree.js +++ b/doc/html/INPUT/sources/static/tree.js @@ -1,4 +1,4 @@ -foldersTree = gFld("SALOME v.1.4.0 ", "", "") +foldersTree = gFld("SALOME v.1.3.0 ", "", "") insDoc(foldersTree, gLnk("Main Page", "", "main.html")) aux1 = insFld(foldersTree, gFld("TUI Reference Guide", "")) diff --git a/doc/salome/AddNetgenInSalome2.pdf b/doc/salome/AddNetgenInSalome2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..34fd25204d7f2506a236b2629cfd6157ad7c1936 GIT binary patch literal 70678 zcmdqJRX`rux&;{AfzP4wZ~!C>t&AN^@R;99_T?az}Lw#!lLoP08dj~s1T}x<}^bF-OyA>vc_G7X;BX(qd0>S6}!a7;x ziNPBEVs3~D6Fj6G1pg1PKB2LnM~-(?ZeiVyf%6EL?JVkNeRuR;?^iUBaMTEW5}y?B zSDvCodZkNZG6w&z zz6Dtdy1uISdMRD*KKbeHYjzF$$p)z(M^b zh``o~lX`|A3Z>F%nt!N?4$%=)NfgPT`%jv(L@gU2%-8#Ltfs*C;C`oR$(so{EYfS5 z$0R?{pt;^V0cG|7;1^pNH7tg&;6&7g;#%?1zippKSD(2vzgi&}Hr`7p0ZgSRc zcjqBgY{Vm7S0IP0V2b^K6#wuZ+@I<&0zMzRK{R-;r(K$MI)GO>pP8+6)OEKuec3Q> zL;*#}2BCQ7QnZ(<0^-)@>aUa(;AK=0Q|R%XnEejL&flK+Hhg=>TRNU~}o;0b1k zys=eEXgU;=kHXW$v5Pl?ebw|tt=T4-96YW8*)Y}VS-C2GzPWA4li-BnsNX}cZB zu63zr9@^nuS&tH>~jl2aJggO-=ZLb72-JmO*6YxNbXHDex>zTfeh8bKd)P z>>oJg-;=8yzk6=91mlblI=jvOLXMoSNlHj7iFNe?E%n9Dk|26Yr}5n+3eB#l691V` z&5&`vckP@F)$gllFQv|06o<^F%vLNG?pvz~Yb~uj%-XeS^l-Pf8?6yeGSiqVduYCM z8TyIFo|?a%0Vl2Bj0>RAU^U_8m;A`_4Oz5{F#saL5tgv2b)~7H%8KlvOY2ClAQiv9 z2C0d<2`Kfrs1=zidK| z?s=Qx+7r~v+e_6}7zL+37h^?NBQ;euMP1*`o=P7XrEiSthtludeT42so?F~2#a6TY zSiLSD49n#+@TzwG=@Gy`B_bsYX}84b_NB};(;CD+ie=ce8a(20w`Ql})caQ| zWDECtn4xmD9lH~F9_r&R7WTu{O;Udvxwhu7*5Y=fadkogPm5ruvXeWr7I~XD&)3o^4iFyCZELQIfn%P4auo zo+EpYZ!bqjl2QPNZYtf!&P1W%*!r71d#voWVFOlU54A#>C@jO>`W=ysH(ys}?}Q`@ zoE}S+mS{v%Sm#&2E!NHxduy~-;_RDo)_&v_zXDiwH;Ay`bg~Q4c@V1U-l0u7Y2Fxy zfN3YO-@J-aE&Vk4W}dF-Dc=_iP%2F}l_H6Kx6e4*uTZyfIHq_WP2sHPb~ z4u2_g8p|FxIEH=1r@*a+%#ctE`qIN67(yJDILjD)Y({MtT<*%0Dp3CHWkd5gMQ0)D ztm{c;=?)Hy^~8}4*)|KkE7CBaWEH2>?xe6hqq1%;56r%Nk!gx+ags`;^I5%hh> z=n&-k5Z(vnqI@D~l|a2vmm~BD{b2C?3%@-SLksj;F#mJ>aVVD_XzPMfU6;egyH~CU zN0{LJ5nj5W@>)D&(NX3Vt%Mj?d|-#tx?(KbYHnU_luTjcBO*;MRp5d-QXph~Ns__4 zk7F@{AB5Gb3}fUX`qWaOw}ga^FV0Q3*>3|Z<>^maE*<59tMI?1$%*;nipGp=BXl!c zc%qdK_pWKRWDwO(C#squuT5J#=m~roQvga8GyF8s&BvF%Sz@zoI9O4ifRJ>NU6Y8N zNwh2Kn>b71P`xM)^wDnUihR<)k3q)=u{p=ws@abBnka(1C}&+}92$n* zc426+m@gTg`S(~NB?l+^gz>syQVTwh!10Xk{U1wy1ZE@1A^a0cP<}l-lv=>6k4lJs z;~f|S)iNd>zaVq~cNfO{tLMLH+b&3qUj#K@pwsFx%=J4%Dllz6DyN%|mrBlW)$RuF zfyq4zR2GqzF;fhqm^4xX*~0zgwc-CvxdRq}fv74aSaon4VALX+)jEmrt65wnG&DVc z(*HUDC7669`61P^2R~iDL@&goA(c-&X9iD$cqV<%G`k!KIGtJcLHXRHGsKGHVqpKk zOnVUy1m)5q$Jqpk1p*@;wSon?ir{vF+FcnUc+aCpRBXWnv1XS%%Sd!^Z<#S^6l5z9 zdS^&;M(!AV(BwHg#JW8~Q(49#U@e9lM=O%;#l>y;_(}f;QB%{>|MMlT)zMTVN!$k` z9aoYQOSGfZ5Y7pAMChlRLg0xii}kdSA@pc{ykue6g#sTfhTG32Z*c9lLqYKo>+l`H!4lam%+8%d50z4EV|pbQ#fOOM?!cN=9Lh|LYarg_s3258iPjvNah$iJdWBmX zgGQF_@Yx0y;~u;%LiGw?X*2+-;QVM1ia3G;ot{YN`092GB|T*C;ITEr>Z6eE%Vz~*v_ot z6J>e7i)&-uDbcWF1qxb##SpQ9OCvl_kpmx|qz$n_ELH z;s_eHm%%-FE$TgsV0`fxrit@NuaQVeeQh2R_Vs_ZVzDZGS4NQ}pfzy$izpo-_+=)_q~b|0s9C@uRErGWfikW@+)K zx%&g$GiBk`^`s@5rA02QR|jN+@Q2+pY#+VWG69k zG&Ii6q0~1pntJKJMGe#`4x#k|jn-%_hS5axPL}|tj4x=>^<4Dsxo(3^`8VnWX?vl6 z1+I19&X;CM2M+89_2l+kE3@OOdbLqC>ja+$7GkP@C?t8xQMnism$@K2kGXa06=lh? zwuW{dm^=Gn?&veKz@2`Etr;@uRo1;@Tf`C?$_rrXn^hcU?10r%Yd_cT&KxCl`&eI1 z(kf^+(!dqY3s&DOUKhqT7Uf(ADLaZQ>{7#Ow6UxI+2?OrCGK zaEV~&(={?AwNyWp5PH2qFImQ1Xho9=;XQRkntsI!*^>PFnDG7kS25MLRwcwqdDVYX>SuJeJ=HEuU_= zqC{zAQOZDVGD~U?Fcul@oNwThoNpy=aYm|xEStptNHk@za96T=?5*muEtUxbTUr%- zlxJZ7d71Y@^Fx3j6Z33$Yg{R@J%w@jOL)gTiCk3pbzPE9NX~9y>`rBlYiBJIM zv=pBylZBNEsWR+Nu;bHPKl2jD4k;BbbX0WxFF;d8I?0-2N<(vmxYv+U zaMa_%CCfb{Jv~$Fhf{qfq^)2MY132yI+c2y6v=`6+UF@THiT>im)#nnx@H8%wd?(@ z?_r}g)ss#^ry~AXrf4-9=Enew7W=qovAvkdI8&T*)^6D&O;tyZ&@^h}&PD zp21zajOaZ+QYIs_7+vdh=X_-6p0l7?zK=YSI=zS+Ojz@s)Nl4XnSmMy{^I(P*zE=` zlpz9!Yvu_|H~5LF#MezOZ`*dX4l}J50cr_8?*ej!+UdLL&oRf>HVNspPZj;+@TxVG zuOf9>7%h+aF@OtyLx%f-qwbXcqwab$r?x)l_0!gl_4b+iI1ke*Rmuc~87QF*?V{aj zk!+=;pd5qQ#w7A6Cdc6~sy}@|X67KQ;x5#*^+$x~ojbjE2Bq-^I)+7jM^|ciJO$!5 zQpJ>xhKv;j$}c?lfc0=gCcCw&S}7R-BOo6o@Oxsj7ta344)-Vmf)Xo9_qX=(0Z3BKk3f|3Hkv;;V1?- zC;syVYWv4dO7UEzj$qeM1eu>b*r;ilUV3{v3R#pB%v9_l8CNPfZ+(cfttO0vHHQ|$ zZ5GrawTCWZlIQS#^GuBv)l{7rM@tu>^Wz4%XwQ6 zAnLnwd~Pu$N-XdZ$QG|DReIb1kOYo8QR^D<@hWZ*oKGv0TTkh`Tcsc{!3fGCcNs)R zO{{IOw)29@3+ym^yXhVmIQkdmpuz(L&V$O^#HA1oO|=zV(U=gFmlt8gMjmEQ=#sOSc`qZpS^T zrb`MQ6>>LeeImJE{QjLH0`CCrB~xbYBOXy=I9`2qKI6oX=Bp6ZX~I*pA6}9BDR&9- z7N2i;@?t^LBopIuT)Zg!Jh})I!i#I3vKX|1JRki&3ulTDFb~iA1yE^)Do?{|K;9Qr zS9&l)t~Vyq@t2d+e>?UETZSE{K(5K4v@K+h>+MLPn9}Uoq3hF}>}pOVo@^eh5d10- zxJhIqThQAj9_r+mAtRs~YPGF{BSvegWxnbwQ*xqN-!dyJhd#iQDA#fM1(58|vP)1o zZ1yc~+4%bk` zrV_!g_kc2m8mZv_Fcf!1DQB(Y*_Un70-4x!1)5X`oBMpC5!4-E?%36n9{u=J=V|zo$`RGKT)#4$_Q~uZfg{l`BcFGs|AevP!)T&C zqy6l!@8Drk+?k2oT1PpJa*<*pP1a=g)9o0?`0LT3v z?o#mQpEueC9qBJ)ewN#Z-eiqxX{zgDH$*(9D+6_t#PKPb6=4pK%NKoVz^P5La zmb8l$YKBZ8WYM*r&!QvGrC`?AXD|Cw)}8y+@iJwtW=TyJ#et-l4x0Y(hB1)7`JOMG z7(Q&ivL(H}u3EXljvL9XneKUV-%rB*>O#wL2rC5U920SHanI*c{%JWh*u# z$pdJ`8oM-_whfarYsj_zL^>!!MY=SBp+OdP)M7OAI{1s{&qJadmj9r_cZz$bLRwaq zzo?M$H}Cx}{P#x-M#lfy2L0G-Sp;R=I#VyNgq)P7df;9mWEPw$LP3o&`z)%3uOG)x z-U3;>CPc{`lq+*PvKBj751U7O+uF_NG_yfkxNBeSP|78}F`XEt+alVa_ z9zr9w0)IyNmrp1XId)(8fK#ud3nVzuaskt8yUiY=m3KlWDiM$&1-dne+a@e%p2^|V z6OlEu+(;YLJJ;#`aR^V&&TG?+e&buOBpgSHfv|G-E;jOC8`u5%S!x@<;qNcJ+_`dTk8E8%;gD*>op_6Ax0KuJbGpPYBnm-ioNC4rsJeKqDrys zxW-Xx!t`Y*jMUnMf570mr(_A1qS0SUDjGP7+cgVmtg`^tlbngEC}<4x=)px=d(Dju z1Fk&>*~plEX+RklS6UAs8OOcK^n(?@ab~fos2Vhb#+k!;U}?0?bj_09oRYJcd|G~1 z$gkEAqyKT#5`tmG8|HJ4PYIMo4fW=6%5i_G6+K!-;oPFdsf;|N(wOG0$D(H8E6CV6JPGxUq` z=}Jxpz-yEMzo)Qlfk2hITv>16yQp;1j=U(r}cXta;a(xEI@@NPb4U<0p z)G$zx_ulMV#j3J39gCY6QR)_qN(S2>y?+f_F%YX5a<%H$J+l)n$H7p(f)KGkBzz_ zZ5TfyDdY-%0|_B8#@d4uR)9VwE0Ig31{Gl~p<%6O!I;Z7Uyk;R7(pKGhZn*Ah z>GG#w45-ekpI2+Q6)F>V!c7vBObU5Rp?(f{yz2Z_7T{=g>6T>j^}(=w*abPMGA2x4 z1wcHG2JxiEjN}JVEi+D3$G)~8c==9nkHWH?{)2npIrW`;>1k>I;$9}!e{e4|&HsdZ z$Nu&y0R$L>fmt(lOv&(bcLB5+^X4)~FIf`7h)ZW;1T~pF85gN`RY#+JoDn5ED3bNu zvQN2^v$S*;{Th{(FFfMK?uti2?YiapCp;o^u4(j#@(uPDNIraDFVLUcnM%TVp?EMn zXb1=LlUcWSK5nP?mF|Q-$UOPILKWH198d%J{wHKpLwYR}?Bv{Tj#h?bEB5 zA&G2AA%I)85%`%u-`;~Yo+04SZVCK{zx?IX*Ij;GA)iM`xwfBrTAy`NeTqMn zP}5a`ln@{uC-MOck%KNJ@D$GtmlW0i5cvh^krfh!QAD4vVb}=@ZRnHXWP*@QSDKit zZtedXMZ8EwzhM2f)iad(0S60oHyXHd&3xlmQ z>DUVrvL@I&%K#VktyScMJN*a*#2IjpU{S1r95~?;Y8Zr_Z?^HGA zHtH5J$#^2bKF>TY+J`Y2Dj>94j6hf^?h(wuvNMbV`lnX0%WWJwCi9-JcXj&b^LG#@ z6LD!4qlM@@k6YXBOh-HZbaQwa9)lI-!~y|1WE>-XtwjvLI8gk9J6Iy$&KhzENkKkh zKGRV>S|(}2lRYR}v?;61-ZG76LzM+TMIPs~D<0yLL@St(SdufcT3y|jUhRXU=8DEFyn5w*N>bzNXVbkh zR;l*pc2tXHVW^I8=Aq(VckGymGNB|msA ze}IHp)-#_9jik&m+p@^iBghyqD~~&pi&#{vp|EEi%LQT5h8(FiojyMMzz^Yb8sK8q z(1Kz!jKJ-fDgoN!(@Wc%3OeZkql@X=XGAqf2N<;Q4<5kC$14_fP0eU|Wrd^yIC&j>Q)HbhEAjQP=O z-wqC{8H~TON-gBcC6sVu7pl!5wj-Z=1C?6g6Z}Ig-bLVDEErh+wNYng`KMU?){pj(%Ye8z`$*5oHXv-w>=E1K&tS{huxM0H>7T$f5c2{uDGM z9c`-914_pWJ#qlPH@v$*+uRH@xW9RJr6-;CsB-}xQXZT@1haXoh+CpLN>=$q0X=%+ zd(HX*l7H*EazC$nJX|W~r_rl@DiNcxoMF0w9N$R1;SWI=SQvv}9}gGn0(U|KS zBGaC>o0X)cz|7onRo-UXD&_Z|I8F_96PDynn~Rx4YRPSEfsrGOs-rrc4K{O8>6MpM zE=aU3*|0eSuG@+xiLObdc2PXXe_q;v$x|mSaY&n?W=zBe1wD&7N89|F2-DDX#}=%C zZYN>w0xp)b??SxTuvq>K>?8oC2FTuajl^qCT&w+sX))LElG*~X9(D<_0Rg@F&*}Bo zwu6zD;jgX8?^nJ*-vSj}Z43c2y2ge8NkaouT|R3UJoVqZ5=K@=JQfBzO=y6ewZmH? z8y?NuU3P|64tT%aG`Y88LwjpSJAFg@w^vCSJ8OM;LkD%hTZSASK*7+(;jNyai-WNI zdsW)^#5ibxko8-2+TSx<4*D%64#59*{ua?5?{_NQd(j*E-?-?0Bluqj_zs8ucY?=% z!Ff;m_&Xl@-zgve-{4_*-xB_3_q=~r`#Th@0QRXt56R5ee%mezt1^2==Y(PgMRN}Iq3I> z$w6!4y{%=(x5dr;w?_XhbLx+0@asD0T38$Z^{{_++@GEFH*4y>kN(9U04ZHdLx3Cu zKtT>5YVbxFrVg(E?%Q{A`EzZ`F+jghkH200+f0ySh5kcA<=$S(Xy5w@AVZUccS}utoN1u zuUL%G^ncz;&jd~X-v|J5^sLbI?_vKP;C(6n6@ZZzn(?nD{Du3ik7%J8{w#g_D$nre z6Bt;a8U72*`!f1hEGB5iKM^o8Lo@!7#w^D~1I_f$<}%SkGyPX5y)S{kV*RTV0dh>t z&`f{EVy1;={u3879W?Vhr~JEN?{oIA0L)C#%zuJmp@C-kZv_9Y#q|5GKWn{DnBV*$ zU}&#zXKLeMZTGG=?=weUL`+^)frkH-iN;I-HPt$J^TZ-S+3BVuT3Z1U&n?}z=q_PZuDK=f^P zo9gpg8C$%GB{V?Z!O&6(kM->WuamK|sli)*I1|lVxumYk-_K0#?MmRsd^&4Zsdy4{!iD0-OM@@6inZ73-}LZ_Oe5V`uP|H*ZM)HUPi% z_-~{9`~1&QmUq;1_`O~EJ=(PVeWVLd`h}u??#$0cwY+W7s0&j( zUN60ExKlZvu&i!)?!TUT{j~v#KjVJ(mdq~Ie!G@=@45k?>#l{zj~fcC)TlDqZ6QJ? zURtc|Smym2R^m~g^HCm?0ZMeZ z`eDSWUa3%8fdrj|Ou1xEZ2MC^omQ?Q#g|;ZBuWoqR%!vvTshO&_^lxq#%Yw&xi`zm zWk(G(FnF&Y2IVYGbS%E*~slZ2yqmU=CXKVBGwO#E4`nly$cN{otJKTo(;n2*7OPOVi)EGB z7VFTN#3HRulaR;FLD3G8moIO&DBpyxaOL+Np|xqH9kG?#pB^Pt(qhamKZvg3EB;76 ziWiU9Q>dpM@=hfTE^FkIi~Esyq~PYL^6UFhAQeS;Y66Uex-!*jyCh~U8?DpW11xep zGIQG{w=Zwp%)W%HyIKFL>2?9c&64Dx8l<(KONNRx<(KYYQ31kB>gsezl758ikm_DB zJ=E&xWFY~>u;4?157ntE5~Fzi$mYRBy>bNc$)W-X=LogIFTGgZVbO>n!OagXI(neA zu^0GENZ$A!P>INb zJPp_AGcHeDpYFUuXpFH|{~#h&^Oqja0RkkpuWqgp?%=n!=N!^G z=m&_YV7NmQqE4i%>}Eq&n7G$&>y1aQl<@bL{D;RhBFSB#-y5g2>#_%?48-mihq}I< z9p~txyCzo_ttyI6jk%}6DPUpRVzJm`ZfrERv7r;nL7Jdgtr?#AW2i{2r)_X0 z`x?I+Mph=y1{ida^asozW~s!vcPn*;g>WM6hJQf8;L;_)2n2t9AjWdLHRC^4tr%)9 z#Ziz&H4<*p@i#8p}HWVN?L$x40BiU!Y-v z1@HP+Ry6j4SC`8dUu=C{??|b35bDOvc3w%(f`j^?bwoh|PLFYib$E=vsj(McU!WKJ zs=-R!U%gH}$n8TtPXsz2Zu)}}ZPGKlr_gATQf}_|zaQm_{48F9lC>(Fk_Og+T57n^ z`@zZ6&Ax)Nu(4o7yOa+n$=g&~pJJvELSb8RzE*(m&RGeKJsa{%h8f{^RbJ zOL~l>4G73`*?9QgS8KmXM?OpmSsqY@_gvn=G3|fXK-;tqRW^>ZXefF=v?UMlkTk&IbWaT zyV4{UqUn+iz1}>CoTtL=KT`)+lK&REPyi;O4oRU} z?7CU=ZG}Q7K(MM2{dQsHRT?)zxx+E$(xqGLEBbbX zzV$k7R@0+a{UTNfgI41%uP9}^jae9C=byVl1DEVb-4>vEz`k0kyVF6(T*|js~>5 zq0zdMI-RpNX1Ri`jV{YI7Gq97Cv)?1s;KH%-y^NX;qi3VoOd8MpQvS3>?X*vfO>-v zV?$?OGp*Itl~7v)L9pi5x%3)ap*b$OmJ1DYH$lVfEWppMs_OZ2UC3P)loyPq-@B~bz3rO3hvX%O0w<0}xqX%xm4lPpSR`(x zVK&6`ka~6y8z&9lm;t0M6J@l9HIYMb#hnc_?uZLZtQ$fi;crc9<%M2vVLO@Xqnz^O z7t{`0v#(+WDg<^?X|uOXujNZ3Fr}_-mCI>xkpRp60unm_r;tohb6pnT%33yzme_zK zvz3-MVOIrov{p9f-=eMc(4Fm+5Ef$<(v(IlTZQWuULfA@-NYHTe>e`jbuO_}5Q2QjCLVX z8J6c$~j31Rf31RtegQSpTkSncaDc#iuMc}U7C{a z5kCD;5I&Se(rMiz4w3XO(Hj(3qn-O4I3pq**;X0K%xQ&FW%!cSo2To&{Je!xWl%xV3-q{p{4C9?%W9U;)b%mU4LHK{ zPPk`64>pjO<701U>sXiu4qAzbvw`AV{89!b;dds2>9LST9hsy<$01Lmoh)C{M5G1H zMoZ0GLO?j?!vv`bkzT`&>ypB|FE4g1eqw$IsN?sLU2J)(K_5tO2MMYoRHWn3}KxG=amRd4l@Fq62O90Kywq+O|1kPIPv@{rf;&T7+0yq^vvDjtI=Mq&Bz znR0XoiI7Tc_q_*++WR#EHR&@YhFlFhJ&^>rn0*oi5dB2Gq-#XOrL6+ZXYfri;n=ph zzS{S3SG&3CeTrkqxj|hGF&FvyvowXRI{!@4?58+vLz-2a!^uVaJR((4LlKL^a|7SB z9dq=+i&GV1+Pa%bDaQ7tbXd8;Q-4&_fYn;NRA1`2#maYd83%)pB4TqE*)RDkC#S!Z zw#KC?wQtlKBTHMh+uNP@mh@w}p3e?PQq_}>*x0_oV=+{NxZ2+gAynC|w9r5YdJq5d z;I>iV**v+#@-$mb56aN%A-k--kDd@ILJ;DgsF=E%7?Q3Ya2D-kSwGErB~o@cjFCVi z(-tF`sEDBeYx`A92q4sqJMP*Yp6%%-0DsJ=T7(Y0^3_gUN>8w4UV&+jnWS6q8HsDQzXsF zsYDMDbd1>zlI2-MfL{WF!g~G5gqubkM8b7nC;8?%ao+Nu!P)VpM$uGyI>C_KKXppR z;#eT7;prBDiA*25e%Gp_fs52#7wijo3{Z+bPtwXzRksA#D^=NiEKB;1>hCYmII5?S zIX38^InX{!Fwc2rL#7m>ehI8HbaS-AIDe{p$(1E-;D<2!YpeMzztBZb*q^3`7kq*z zRF>%I$2L4M_CERGHbhz^wxore?a~EDrnKDzE{hw(rH@#vm41C~+IaN0CB%N!zj@H@2dh$a}vl|1t21i)@QQQsd}xe^37xb!>sZx`SiPEAd1 zGe3~h3WHk-tP386apk>>psv)h&Rr*f!DY$<1bQT^o<{4Rk z4hqX?xRR6MS4=r&SF&738OlKb3uY!HQJI0Ur^G`xShP2XiBiGb0D(f$3gc)#?519Q zT~HB|w>W9g+xD8|;KRrt0o71;+6gO3(gO(@FRc`sv)pNe=yhiGl=Mq$~=f+!2XHU z(i0;iV5(kAs7r8ZYk}y>BFF`mzr zTf+G0z34giw`og%fplOe>-FW+XVrV(Q(=KZFkpQ+osC0>2PRNDV(P6W3mg@Q7E7W1 zrkt2C7hhGM#LejlE92Y|4jCmi)pkkz84C#o3r&nlesTfqE|Z-XsrU0Rh{eG-6mXO9 zpO*9Sz~VTA*-mVBPMR!B^W&kJT+2=8BDR(>ZCDEasp&O0IbZd9AU1>10`A5vOP!M6 zHWl&vtT2l`^KEX~h`Hc;6phT74Hz{I{wh=7y1B42E6{C(wQMuTpnuu%TD3DacCwXq zhWeU=CB|w9<9sz)qxs4`>iX!~`2*rAtc=M##!A z&!Hq)!OGpqZHtX3-|+t8_BJvIW+Ri`dTJ+uB14$TE^*pJojSW_Z0}_BXmpR^Ed9)3 zZ{Xou#lxlUetksJ2G>dG0xG;NV!?}rPIca4j|?vA5zMcygFV@WXb5>O+D zWBJs1$v(qDm}dEJbe#ujX#}k|OcP*|e!IBlI9A+dOAhML1!ej%d*f$KZ*su_6($+| zV#3fQh^4sT@QTtiPADt3K=UXB#x;_SO{mbdu@gan;obZLXkQ1cwq{KAQ4p+w;|%pN^Q`{~sMOn>Uxq+5lj0p=)pQU(VPc{+F)9oAt#9;D5Kjgx?J?i8l*O3Lp)T z`O^qfd^5sS0IC4JH!tjuK>ru+m+`y*^>_En_Fw*&Gr;A|0ec(DHz5Dvc`^T&Y5jiw z|Jw8V)0O?3=LMmFqI{o~u(l+NkYJ0~kWmjDx~R{bEh5W7FGuQ9k?`pGEwj= zPz)7H{vs6lA~Ezl8mi<}ww^d;2!?+6E2!iT%!w}>j~z>3PQUcp?OBXdT<_c5H`+R$ zzTZbeB0Kj85XinR`F3?(??pf>^b49Gfhb(Q6**LX>t(v~^v8NG-86C&nP2T&`!Mz?_Oq13imW zT8@z9(v1M+iqtTNjfn&7P*AuSIo=4FA!PW0QR&p`3bZfv;%kwLV9uk)I>r3c5LhFe za;d)jsJo(3G4=Cso`9f5-FKoqI~4hZRqb(MMkbD}j3l%~#-0s&A}%}CP76f^lTEC8 zJ>P|&2ieU~=1BUV9tp|(JsHEE=L0OlVWlI(RE}uv;yvweZq{S>h`FzU4*1WyYBm>@3jaz z3I@})r;ALhYyrgtg&FdwkE=IQ^}&MaQz)38eHGcF&giGw9)U%PG7`C*ZZ};V73)!; zI9q-2XEr1==qx;4| zJH!*t(Np%hH)-lsHdn!{0^{vsjFUk+IBOpZ_O{ltJpes%rix%P49r~>vnr;vz^kt` z{AZ|LIafg7p-ZSzQjFEC;#5b2xsYmBQ@#$WRzAH^-fMLmQw_w(uG;Ppa6!^y7HqprV;p#}{uZTfi zZB{HxOA3Qy8J5^PTd&rBDJ6+s z0wdgD!7G2_>h8RqlS1#e=p&v$pJ(CbE_j^{?fwsirOM_Q@&@Kq=m zKp-i(6m-|e ze(>#uPzq6K9m%1fG>-c43p-iV*LD*S@=bG_Y;lMDg0OH&-_x%D8@q-7Hcwh_A9+Wi zX0C^G;}B(*gu5LE2pn-|2jM5mylS4V(6j3zfWS}pT7_U8efpOZrIB3oQfbMG+%)(T z&e3!t92YM}IdJiSCjD=Iz|b^;%Wn7+#;bw{KRBa@Cz@GN2!&aCw5p`jVDNlUIk8VSDO{LgeCS~^3rGe4*(%<5R2Sr?o`SsYQ75Slo zA;l)GdDZ5MjrJv=ZX{}l1fNC0Us++L?U3K}D*O7zv|^k-dieb8mAF%qobG{XQoa-B zB>JSkF$rUMqz1N_gRbRj7Y$BxOXvWcNh}hw>I=_;6%IQ)p$w})G-aRC626i~_F!EV zlSca&Wlih)Pc3S5Yi3csTSOHybSgHt&fDBbl?;w2H=6{uHpOi+dQc#;AZ}IWj~@l9 zZ3wjOpfqUfYizr$xcif!)NmX0Zpr5~h@+DU0zf|4;h{a;CU8m?8oE0tDbf+=FbqT& zkBm%A4e{*()XyWZ)_NWpt8%SHd{3nTzGE}zNuZxbpl5Da4L{0u?SDZKAM(}gHP_{# z34HtCE>e0voCHL0=vP=D`SS=Ni63t~+!Z0ExEj~VdyiW2eC8JEkaf0oM7MnxrrrMiIql6KWP%YQn63n+AT2Pp zcl_DK2w#|m9bh%Hu!Md0HPSlJ7ihv~Z75K#mox3^iuv$h(6N>g=wom4A=RNbQd!f{ zep-?i9Uw)WcV)myCT;!WWr$I5qa1=R=>I|8I|b?1Cfb^5W2J4|wr$(CZQELD+qUgo zY3E9tD~-;-YVYdWwd&0=Te#0b6+}k{@`mMf`9Fv-5GusPv%jQ|s^jiUSap4*bpez+rP}Mfx`o z_@T)#71cn0*f(nO*hj3FP^KM3W)RMp zmp7eQGPBKJNpU|%fnl)yOk8u`1*w#g+eK0fsI1XS0`zoK9ulEmUFZ*F)u$9M{1FHI zep-DzTe^uYEwsgzfpTZ-a%HSaJ}B@L-CCgNX^X9&ciRb7rihEBPRx5f_`PB!RV`iZ)K%`Z7hRy|Fx5XI&~^k> zH_4TgDbLQ zJ1_u=VQ5#(#4Dp$c`KLUw6KeE^hc-`ln{wewUz+41qZgzDuJv!&Z?t3^QcdEBKbaD#Z{mHY7#IA7j-s*2g`rBBG z_lXCExe4Ps*ehc=fP$<~LDeZR>`kyH5Xx+@A`snh3}y#%Z%F|>>4bASf9gDgjnVDk zN><3eR;F4T?bnWzZTOq|Y@-_6Bvi{WCL?-aFEQ*e>X6p+u~P7JinWvAB!K?Y{+~3n zq*$@blKl#mP>n;t5|F`H$>8VUiHG%%k6K-hkKOH*I?&XH9gN@=h}(gRoh6T!27R6l_zV04?0j@Lq-MQ@~XvE9bL@>5kWeE$gt3;;iB(x>ZtElF)+RNNb^jZIQQ?1cP7PaE2mP{ z>1L2pGe33ixptuZPpQ*Gcb%gSp>Lbk7MP7xHAEuvHNkEkQ+~8I_)w*9*Sw@{&#gz@ znKc&#pv?tpw^K}|xWX2J&a#2x7dQyCH#6&U{{Z%8@WG-Zv zkcHa3GEdo#xPj!EznNNt$`axgV-8&pVC~ODOU1WuKdK46cDkSQIin%ckd3X#XwH zsEb|gC!WV9q(JSALdlvU3sT#7ES>$HHIU^E7Vq(9;jsxZU8>39;aR#h;ba*L3JMx3 z>g3gB4GqW8k7~1J+S2YKfeoY98o`HEGsQXKpNqZ^OAE&y9*%;6D; zQ?3Vn?46VcF zD=|Z*{^05bd1-OiMuyZyyBGzqt*6+#lgYa1vc8zWymrF4FM!1t{u5Yb5G9X)jmtL# zn1T%^d?QSvXQcO_f{WKgU657rW)E6#u_lzzHjfw}?Du0pf0pK*b{~4+_UgL?rT>-! zuy|^r$INRAD6qVyFGQ#k`1EMn*+Yg1b6L{o#VM>OVZ>>O2xdGE9ssI?b7}ciZ}f$v$;NAoX$1Y#m?^e zX824QHyy~1v&NLv6$w71Gn-ku@xwo$iLhq0d)(h~{hXNgaCVOr>UPXJ3f>2}OY~Az zGgEBlFriL<1I^KSV^vIYpBKdN`SpprvhkFQmfIEEo@4SSzLA^qu zZ=gYWdU@TKO41)yM=z*YQ!Xhq~p1;36f7!?fU_)ZG+qk^Ol9+kOlsymHnYQT@0*s&ql6dRbG7x8L7nD zh!r#BmkVP!ZG0)!YH;+FXe_f0P0gH^WEX@AxAGNxY#<=?FIJlglZJTlmijUIU~y>g zn~b7v>;*-ukRA&Dx_18j{tK24VV0i+RcR22-XpMqgWJ7^dxt^huO7pqgp1FSW~QN)Y$2fG0ZnjYg`cAlF(F+m{Znd1OFy)Aba+3YqOeEt5PH!RC?6_5 zeRU9*ng;)FI`eA2y}G-5CPZbiwcJ&p9Xhsb*~m1(1Xr?ftW3rv%LEetd6##&k&->sAE~nY&c^J2A8C%orPH-Y^ z9G!SEX}7Ol@den4E3&hhubFP`$1m{kq*(KqH5h~5`p`_}ppLVjnD6fJ%a3i@I94l2 zgP(XVwI}EQCIS5`@A_K;%Fgf)0TIhz$mD+{XaCy-R6$Z$T0!u?C7?|IzeqrBU2F`$ z(K`z>Te|OX^DhMP-(!ORoeunuEc9=X;NP%7Cll9iXz*X*z<=ce{~nEs(*4(PROy=! z{4aFiKf=-f6Hf5&N$LNJ6#RQu`qzE_l@_FPaIteXF*daR@9ZGUzd){kyZ#^NsQ(eh z{!@+$sf;YvdIeZgsv?|kvspUY20%N+QllVmtRNg7NW~q1VV^v0AgW=Ew`}N?Zh(NU zth~w3fCCysYAN_$II?AK_(1X+efxAM7E}I+>~X9DKi0${F{6-IVY}5a>DJq^gg7u0 z8ZS;f7?|q*0#1|lBQG{)j)XQU?mqV+fl@P#mqt(>XB0l|hRFIkp#_8dJm!7cY#|}o zuiNNLhbYu%_rbKA=xZOK#}(gzs*Ez>A_3b4_R~CNBN!41ZJ3PMYH=Q`Ig+B$Y*tm6 zn95TXS+_#i#W~9m`_rhBl9ZP~6{XZgtxCQec|C?wB$-pR7y?H3nv<7yUS}_(3_^{Vw2W|Rj{!ALDGkZ0m08-qF(JhoJ z3VLptO!Q(IQWKQ7VP2YBYs`Agp61@BFpIA0keGpliFc9gO^KTfR!yvwvblua&I!q|p-Jbk-f0j?8IV!3AmdA49~y zc?@alvu+4CBlry&Zh09(Aqcx7#)s4g!qCO4@Vz0?3`zFH+7SDP5Dhu^M1y}wMcfWi z4&g_L(Ow zVw4bhQa}A=^D@C#~z>aOvaQ z{k4mrtF(5FD}R$CR_{$KHVHIY%Ms?%W;2U2v-Ecu;d;Pzh#O#x=D{E$*6DO44UrW9 z&;otG9AqI~0%~QQ>gbwRAe|x#z|I_+(c`KzygD*@B8!r`#7$FUTdSafxy6TZC>_p7M)Ee4 zp8A)&JUi&m*lf1ASv7+VDMFN)sBVxf$5@)^3V8LPs^(JiFtA~(IPAX{hPy9wC!SbTmjIDeGL#bXXX&QqCxg;zwtvTL zU7g<{t~at7*X?|9hqc7@!b6fLp_O7fRsg6F=>x5gpCEJ(@92cw_`q!=odNNKYol|s z9#CKhK?@;kzTURiyy_?VTK=J2jf8!Tz@jGF_@Euy21UlcxiBL*8PxBUkellRwLXv0zGYA@}A z`G!hb0j^Mk=neAv%~^lK-r9`~B+S9Vg);4W3-g;XLjl7p@)04%2oRAGVk8neA|?xf zDsvC_8dsJ1?#g9dQpF;eu?GZ8lc_%AdI^Au#RR#AClrEI@-vOQoTBT3i%rf17;R{= z`eN6+aX{pwPKe4lW#aoy%GhHcIf+?25Rn3-6Bjh(MIB_cq*8Upp&?(S<<5ZSfyk?j zL{ci%5ELeFbq#Lh0WBsM6F{%|Td1OX2IICzRCU=76Wm=93@Kk34BBNOjl8H|x!GdP ze0=q<+0y}!h9-=MUSI}D9N5=Yp)nblQ!DqovSH{}*VI=v=;SamJO+uhc?^d2ofe#z z;Ju1IE^ndFK~)w`F>bjM9~cMN-kZ~SJGY-VWTY3F z@j*aIl3Qd1PzrKnf)r9a9gs6PmYsqGqDM$w3u3W0jiCv|v;IadG^231HM}6~k+_4M zIZ5-^e@LweC2Ga)5!20D>DPJwiU8@??RH*5P{gziBiONnlW3sa zaqisqP-~`IL81?g*_>E!jGts0t6`TNwKl+hy?M~(7_j0(ZM-1lZKBp_Au8c*Bu}vx zGoRWWXU%Ta?xcx+Q=N9Tzs$ozo+(Owc73XJY~xjq(V3_3Qmpmv3hMa~#T%ruzlOL(d_BMT%9&A`IPIJwGkEi*EzUaBVMwW^UEXy|J z!pM%OF=T4iYw3+pLFQ9U;PxP1Qed1vX|oSBte&^m>d90*YBR$Uf!Qn zleM=ETNwCi4UWtrb!?>b3@(Wp@e7Y<%`W1Ce!0%*o5$%+uRMd(zmss!`jw4Lk2bVI zzo)J4gP*sZdCWz#S;bvo0)G~3sy*A5P*2s$fMQfbQEYoZVvrLRv_5nISPzRLk|#C3|d~aW$UZ`Ot0+>8lUYICl`Xnj|c@aoJi5j922F zH||mZ>w5;(#C*L&LypNJR{?8h-n^Hd9M{jG+E$%Ewc)Yu{;;nhmR*n!=gjn_$)r_I znO$n~abOZlG6?auJHJp&g6E?upf?!YZU{eh@gM06Zx77Ek3~uzl(Y$VIESOe*hSV2 zKDr(uKCfcT>|GXTk-Ha6^hy$MFi1N{6rF;f)~N1KUJ{Pt8HZ*t1UAj>(VZzP%5>CW~bHK>mej8^D1 z*H|HA#9B#0!@(irUDxPWY@vULi|H@TWhqp3EG67Xk2wd?UFXyp-J3rZr7OMbPs1V{ zK1I_rD}3zp&`9#?_hx!K+_$d>r<)grs8<%dQFTbLGkWpzA-Snx)T1lL*W##UEEJ`q z0bayVBXLteh@dx|r#cDo@t>Q_QF8rKgJu?76Id1c zV2QILO7Q()(ybMU!!-ZA#G_N&-uN7l>JTQP8>Wn*_HqlD9gN!d+{m4HUeJ$5ZtFgX zygw@^Jv8TJaPFb3NpU=|S!O|Y97Zh?BUaDbjQB_0e+?#6ulI;S1MU7Aem~yMnzwZ_jWauCUGd;^ zhO(n3xKHi$VOT&xK|Tx$%(qy=XkHq@X%^+UnsF-P@x&zXB!Mg-9gNU)X za-{wu0-LDbzZC@2hZPkrk|(PR4d@}fyYV@85+}byamc1abm@mnt);#BU~?4JOHxaP zEt{&ksCxhX-hhqj`xVwpP|dvq68iHy5z|oc=n=T7D+@RVA=;DJlicGon0ugAQt(xv zeS}0)C@$~nYSD%>yK7#U)bT+bOYDGWn$+5r$d?OEu&0idr`T2mxC<*$EnQJnyP(fJ zu&1s<3ju^1s=>(_jz-%}PPJvw{Uil@^6%b1PNi2iWTgyFk+yU07|}oo2W?>!-?b2D zm{@%-D+_WM)j;xi*H=2PUnMOjF%oD4@23nE$nh|Qy;W{NwTwJ}NU_j2=Ny}+kdzSV z_@1?8yD!UYXP8VNAN}FEcd8=WCTdJbQWnXa^zY- zK14PUNzpfFp;ty;SrOcd2UkTpO3chhA~MgE#>`J5VU0B-=DzNKH)uVI!Le|N#k+<7 zH0gJ8=bhp7+g+_+1xD?CQE=CL;5#%VxI+6hy?2e}vjG&q0u!M09`3XF?$xamE`fye zEF94`&wZkD^IPT~wZ!|%9Uu0Yz_crRJ?nhjoEl${ZXnHN*Qc6$cd=DAaQR3#vnm(E=+tuho;h1taYcdMDGdegXrn<=rWge7mM`yLQdbF&OS@>i z!08uBbBtWPzZVpEd#nH)#OLIuK{te&Vl+}oPDDvfgfw`B_j`oRn(^P~e1u6&lY}~c zQ?Mp#)_Uy(%<{3^Cis*JNILPF$%Wvj_|=51Ehpvz`=~!;_L}>U@{iqqm)gekaF+}B zv@3VwF)RJJ-eYvLvE*J*Z-?d^05SI+>K+yKXmc`D!b9LGkGF zqAI3XOkSEh0@&U$8bt`ei@3gHc>>VF)a(N9G*0r3^c6LypMvDM5(Pyy1Pgx{yV3+U zB+7zoi(>@qySvPxj}3qsButOc&{7ZTR}%IG(Dn*r2u+*V9LcAsC_!G5L%?7|KV0sx z=8o7efIoqCZC|Is*DbUfV>J97SC{){&HLzbL&5HZ^=ft?y}V|6_ypeh!n2~_{!MoI zpIdikRSt*f!%`W8(tu1_+O#X@BWM%mKrkU-VC;WeN)6DR_ zng4$}YW|Ov@_$Z_|C$Y(e9wjLz9Gqf*#ZA;F8)tD;J>c_$64NgjEVn|<*6vzSRUKQU zH|H^RK_E0>{dfV8`k~PW!O2V+fj+doU^G{hPGkMniju!zWWp+xrqLi?yDAI&W!;*d?~+#|qz-m$xooSOZMa zH0IbMo`i~+p0XTYEv|3Cf`zlfE4mM9Wt;iNz{N!tcfZo%VYUgPyUlPUN?sAvdz8Po z>_N6|oj6DM|eHu4+9#WSLoi@t#k zj@B_6km5kJwh~@{9eXbK2(-=Li1AcFSU-5OvRm5$)GUs$4oAhL8b zwSHssBLZBvbb7{(=B6G|kgmD6LJ-#|E;viF@9v7kO{$7GL#B*Q%4yz2bZxvy^MJc^lun=9JNzcD zZAmeE>GMuZYMFnqK?cn(M=BZ{&ooS|2DcL~Y&WALXld)S-;q2lt3=h$iX6;KU(9Th z-+L3;BC4s+RA_zSk$)}bzAac6ZA=J$7VRJw2I9~Pe;19e|P`E z{>H0yiDIXD+MBv_OvID(qbpm}a-BQRJ!r*TX~3KL_S3mHcN$Q64Z%DbcG>#?#y%EI)Z4HG_|$M%77>I;4N6hx5w`ys(j9?ukHL#pNq*H z!PSk8NA}{>_Ir0!TGMYJO`nkPPM9OntE265J`tHPhAZ>Hp%^L3Ed#r{FU{q^ZDKwyAj;hcYv`8CtVq>7(;{}3OS5U7FTB^>Fd*=eB*mQY4t%)yRvM_jbWl-Z zzDELGFErdZN&s?t8tyNoKR+Q9!sojRX+u=$@@S0;IvZ=L<~q`{)o-R)Fy!s>kwzeK zDiSge%^^xA>F3D72MLtOk>LhJ(W65R8DBB4>1C#dxgNoT09WJT2I;XO#RN;t>zWzB z3hP+bm#xLulH}9K#N{GD3a8k!tERFf6utl`;)1yU&2jXfy8#A9cGkas{_8o*{IAZM z|CL@tOhrakP2*pWBVR_-e>#f(KdaaH=PK>rnKu55TjQVGvwu-+Sh$+}w-)W+DmMQ8 z%HS{AhRS!H_SeSX|9DyOpI(i>Rt5jVri}S-hL!*Obp6})|M+zMkDL7Cbp5t$s3WaB z;sr~K3Mh{NwwnHqBv)KfL(vjI5C*M}jD(g;^;f`87tt_=hTI^bCa`WOmv;b8lcibI zw6d9}ZMj-fwW_Rc=GBYZx_Z{x{(9Sy@Q?nm?uCb7dfIfFz3c3ClEsE71q==f8Z67Z ziJx;pP!dXsnCFxUr?ePuT0yz(n96V%I3xCL0_HOX_)0WFo$w&_a#g)UtS>NF-R(9K z-E#0kWr+TAh0tS5wntXZz<%Vy&cyzF<*Y4N>PD+fR9c#NuGV~s_P9S9FH}10rn&Glr33+qa`tyE;5hag>ytS+!eG`Qme2L|2T2jI2oWsiI2pcaq9JlinZ{`Z{y(!|F$}kGxzCb{A$NPid#Q- zFZUo7tdtN7kJS&he|e95dG%aBJb*IkW@p^4SB>ieKO(}}1XBq}6OABXg{KGuFvQ&u z41B9JynmY*0@X)C5SJh!Mc^BPF+_YI0wA5Co|S zbqNT=Nau(_ct-*V>PPbg;X`Q!aYz?v1+H5eldsXp7n}$t;XM^jV zXk)6(XuR6ra&u?*4E9{Slhb}7^WS&L0>&QbXJZ#@i?TER6k=7MYG(0tqKsl3Q|=~U z8Z!`^u`bDJ_d_4u3D-jsb-lIk)OFZ_ zIC2+@#5~G;Eksy=hf^Z(WJ&og7W9DQgd(6AJE%ciyiax<7cnw)p1&AGh%gQun0K@PaAgz`@+wvd2eHL`>76}) zI=cbDry9{}8WS0d!%$5ArF0tD3n7Z{zb5q~YsgArT~^>!gYjK2UWI+|^)q zYj-PQvH-v0l^;&tMKZgD6AoNx9?9eoU-E33fnB9YHx9KtohOdn)HDy3)cthT1O_xt z;3f3laq0krZsxD=qcDW!?u3Qr>aND)Lv7{!LTln5-!Wj#3bTEC&$(>xsP4(4bG?o& zp4i-cjjG?4u)Qbx5whY3%+M!la34Co5q75Cqx>Tp#$naeaQ+OIJLV9c;N2M`I-6Sj zk+IMJ$fjDH8eQ=9JK5SJmJF54xZ3F1*LW=}z4oS?1$`c?y?Upf(8FYXCS_)#2e?XM zPI6H}VOiopu@DS>b$BC<=$fNFfOV6Q4R<7;aBPep>_#lYCIhl5*Ky6_;d5hm&u}_` z-g+5f?Q9;K^xcffK}Yl%LX#Sa)b`_rR~mbr*v|I#hJoZeqqvd*UIGDk*a*(_ciI!+ z+gtLcXe|F0M$)T84Y&&1ZZ>E%g9Ix&6`L~;0R|iKcCRkH)Lg_Ioq5Vjs2r*qW86VI z!8Y6+p1Xnk=7+y~N9m|jE1r7^Bb&Q@t6d3AorwH3-M-{sfpP`voVZ~03OP3-d}9K) zjoJptuOEWrGyS!|ueMg(f0xsk>%5K1UdS!;mG#pN>F{)*lz!Ul5-Jqhm<6KsP05$Hnfs z*mpf(v-foRoM+C{Q1xqCCOBVE*OoW%`i3UakAxXSWik*9s1QEXbcpAin)fzc8w>OU zu2~QPkn*c&QC3jJ991E@dU@n&0G44)uFx6^nXL(Y0Px%(YIqFC3L&p*A?qINN1z;K zKd*YwXZI_EjbGbwdon+*tD|D%0J}VYzX`-?$43XB%GQB+O7y;3yU6eUUNPJF4f?Cy zOQzS!R{cZxO3oHdbopyfNE4l%AyJy;+zPZNRRG?CkC13yxXeFWSFuY|$x6q>>%G{| z2;?JL585mWs)OlOdmU{GWCr#LTri(%L|qg)BQ+^AMI%FNc3T*}WIcD+1UohI43jDj zq#uWvryC2-d}oKj6VH6YcKIi431Q<88>!}D^#s+)tJTs*;($N;K@-O)XSHhKK|34I zH&ni$U9-ZzJ&*D7mBhTieuR{XZOacVtkecLg>lg;geQQ7)Iug2Y+N{yj5F=J`@G!> ziCMw{#}<&?B+W{kI(*3Akel&f+w#O#7rV$B5EnEEjOtS#%#hzgTvSv%Rl4;cb+e;D_8{?nSD^* zxR*{*SC2OvYXotsNrFEeS4c|YMS7h}ubUO-A7tL^wUjoIT$r?8$5cYG%r>CQbZAEM z)-`f=_Si0#-;3FLd$3Y8NSjKsVO4mY-oOZC*6#u4+L?`1hd#2Kbc|@Wf== z$fbmOTESipY7d-YR%tFD*+6Dr9ajaqt9?DG#L6t1`z*eJ}go!APEpfFR)eLfE)1PCphj!C~>Qv|U zOlPxi2gtnOYDdxP=w+$qP@M^DW5u9gEUTM}pJt8{t}uhd!GTpaB`6?ZA-xL#9MXv} zeWgPj`+Aq>S68ky?699KAKW015+e_yaZ0_V;G6lCcfaTP6zvSh@cBTGBY{)>N#Xdb zv1@Nox8Yy6B%1kyBvc(@NGidp-Sj&y{G1A zxHb^l7GL|=29MX?61`wW2p%nK?PxtWsY?1zaJOkQ(Sn1Z2X(KH}_rm51XdhkP$I@w5%!AZY z^|vl)TH2>olX;Ew@uUhT?N!xAdXSLB7C`=_sr8IgTl&q?L`!LEWd%~ zRZ_{q!J+)Z)ye9GfnSHO(FPa`AGT78d?WhBYBj5Fjk;RzdAvhRjkfD{PXxoKY0%;{ z(q0CDG!~}a10(A^e-{c(vtwL_wNl*pc-YowU#ve|Rh-yx5gD3v z{MvZ314PC_1x-{;!7A^a()p-<#oVlbW=YbuYjuc$J;!?8;r8WUxTf|v4!q+eog>?_ zN5?+<0BLV{pzy2n^b!UD{eBzsZRhdpT6yWwo4J+|}nx1Afmz8dlyJ$0)=n`wLmkczJ<%Ol4_j-DzTuc)j~ zUePdaGnq|!KlyBxs#&%R)rZLnZ%so!L__g^PdH`CaA83?j7j;P__9JU)X+2=}&SxVF}PZrcx zP}G{!k3aHf9}u)-l}9;7)fG_EH-M#6MPi-h*$%O}B6*Kr&cz@!$&k^^$=IX9a_#rs z`%Zmj5$13ts2)EveC_JNafj`Yt?l4(`*PprE!p`}Z=-$5_3H#zp6pm}Pv4eSi-w0&x(IhJ^Ds8t1eDzaq*R#?IYJiT7nNK5Q9*d4GS3D}Tnv#wNxtpp{>1 zg7+|g8dgA`gGC7{wG@oRc9|lDLIEF&9LvQfBD-AAUoOPTQSLd>|GUfD_yiV{#FRN= zl$TODr*f@bYv7O$eJ{qBEsXuvD@?HXOUEl1R8euN&UFC~DY?^JEFQr>?)FzK%cmM9 z+R)A80@xrAd9_`1Z~Tm7Rl6LP;ov>Mv^IL?Fn7}s&@g~R*MOUllA4eqA(AE;F3tl< zK2AHI{1J>mg#T$oK}7?MLL?xeAVKhnlb~ly%>snoKhOoFmEhX9gpp>NV-NbETZQXMhHo_%aBSz z?6&P8IchNajs`a~9q}}*l<&0T3kMqtoDBy=XK|3jtxHg?l67QUkvSs*KV@P6PEkcy zSBtW;^TuHm&HwfL6SI9|$V*LW8hn0wy)RK^DT=R*be$%-v%f?3F5p}r?4f{@*AFg1 zDMCWI;{{AK9G|@HD;lLpglYLF)eO}*6N-O=sQwfkJt}H6Idxwj z4M3=3Aql)7G6T>a-)q-9w>~=LT@9|48@jeRhXbm&_?F&t`*BD3!;t#g%tN%YwujTrbTv7HirNHROZSE|u6%0;D|M9O zuxN1um(xNNAwWv%uhFHn+)Y^DKg}VNCAGR+?$$_F{7BMc@>m2D#aot z1B|Rc;AGsPK0*9&KQ9@bSyE6k`6*P2TaBT&#%s}V_JFD=xx{j_^|Z|=jB4`?!ni}O zRSzKdffK9@bQK83&^jV2BpYA&yDuoQ?GfQXdj0iUKX5^^o5&tgvH9DtEPo#}?`0I1 zM{u)*JMkX=9%zRl4gUf!-`hp~H=*i(>WP`zS^x13pl`eIKU%E+?LI+FQCwL?^It>N zzju89>@EKPV#oJ)aq-{X!+&2A{N)w?Ydi3lRORnp;s3H5_`6~FZ#@5hO+WuC2mje4 z{Fg=euVujhdIG@wFV5`0UH^}R&A(Zzd3pa4Y`Um=sUxYO=7uxLhAgKtrz2-at7rjM zT2T~XrBPzaO9t4M zp^LzRRC%QKV4`$N!|#+d&=|C5aRfeF5I$aF43#arZogz~IpXH1Tx&cwQ{`u$JB-gs zhWDD%h#&phLFREMbIDDMC<+V=O2_3aB$_6+IXT%3UXRwSjln+n21v-9CbocYK%eBw zWs5((MFM;=JEimW|9C*Lij^zYQCQqcKp)pD{Z__UTblr4RfsC40K-;A%`BQyL_R@Q zu#VN7ta#_MPVKj+5Dc#vDm)5*n$3Y(~Kxs83m`V1A#%iSuci!pW+Z zsgS2;+~~DF%kt$+Tq}w5@Axgpwa>DH)wQW*E$WZrGefyvvM38AG z912k<#|RNbvY}HDYpjk(W3r6dU4kDb%I{?#P06%{Z#mERNY#Z#qJCJI2tUy~=$qJ^ zXdjf-IsNV_K1p|X>9RthkJE6msd_-R-l-+1Rg9TaR5+`(4&KT@9-!M@pYvqkMisY@ zN|sHdx|Kh1SpaZ~+TPBVwrtFZIt4n1wH7t6Xn{iVpca=i)bR0Dz^nxjmi9dCRU&FR zZD=!rna62s*dI(CRc{MCVBkuV_l4TH?buI-=WoQG=_PcZCSr&EMd!sMM+(X)^m?71 ze&@M;QM~A0tJ0a5=#aLqS=KP9F;Q6kW*Y+XJo=rqgL4aaahdW2m$l)9@!&5sQe8Y< zGUKgZJ)Oe(6VocY4|r4N@i7)lF>}xqJk$I(SKGAIqHtVUd-7R+4>k+p6K*H5&(S^3 zSs^J5#+X{gnmGl_XI%Itan0J6dT{(bjV(SKP+zx5o}uG|vr9%6VS$c~lio3#7fJFf zU{?5{E<({GYc@FQ6>y8F{*5sf&4F-kGVCezCgGhM@@Mc!J_K>@vkW$J|F}JNGXG0= zdyskXW->*)1E~pVf&AD#`NLrmoo^s9O#3(cjCa((BGUJxCukE50zm}a(laCyb3(Av z1B-*;$5r1KWb2wW+CcZPS^ts{D}j3QRR1aVduDBv?0&}wlI@TVGmHESAXE&xCE2e) zPXgGm-`jyg6bWKVqj?|uAs;V0Kp4jP=)907j`a_ZT*n9uZW*KwfJC~GX}D?c55sqC zq|(uXi3G1-}}{;01zb~>Vj%%E=5O5p+o zD@TH_7y55kfTmBWC8V1iwo$)~tIHdIrn{~5+K2-=KfE)oT=tn*C3bR1Jn{LyzoX{a zWyxeKfmi)m#%H(Dh9KsUu(z`!CkMR2V0UEm?s*Ab+@7BU>|!q3uO&nXV(v#u;Wmzk zSPDfd2b@#sVX_6MnwFEUJ@dSuv3XPIh+Z#rAR7I3oMNy%7-t8$ej@q!yaIeqA zCS_1caI%S6jV*O@-un!xEdaT(b#FE2(kEeqUrQxy#=y4B4WMIq-@-NH=cLwwh)wYf ztUjptN?t|ThlSR^+hD~*Kt183!gOgMm zpl7+ES=`o96UQN0e%es?Q@olFOvU}3oM9JxG26Q>p7Uc2irrD%9Zlk&%{Ls1bO|vT zZxYSR@u$=YF4(tdw3xJL-Kf^8>VZN~Fwe*6V2L#=p34wvk)&4u`&D?UYTC*zAWD7} z6`2U!nB?V^MJ;|D8d>ZsDz5$KaAZ8~#^dME$ppQ?e)u;}xQlacuvq^%sm=$Rb=MfK z<)qCb7c?6RyPC~d@cl}w;~KX=%E>JZw!d27>FLbGanjRp@-UcfwijD2)hvRLm?2Eu zDd&O*fdNt6!76XLt3*xW;wOR)@Fj0-UxCRA>-2d&@hHTbw%CY)<5q5ex!fEX0n?W% zetwvwEfuKU=zDl zbnu`xYSO&%o+m9`Yqm(5ULJ$7-Pe8t@TpNtvH*1NJ2-@#Y&l@78J_B|bC`Fmw^8tW z+@Z_e@NkSrxVAYl+!93 zba5;?QwCQq$tWtUzy1GW@0_A5-PUeh72CFL+o;%9#kO6sZQEAGwrx8V+c;Tk@3r;s z-#6!+wp&_S%eU~Es2U$i&q;xMG;hi+$fl|B8WvOitw?du1tjL5{k;)bs z2vE9&7i9M~81F=|pPtpw1wfbk#@S*~Nn4})Sl&RWB)N?n4@S~Hn_^x|FUzKvD$n90 z#*7NFkoJoV0fvR*-*d~-Q5ww^1nYv>ryT2diLz<2l=H_WR2e7{zl5n-)hs0Yq@X}C z?%;MdYDwx`u9YXV$H}WSI2$u04y1xWW>ZFp=o{AA8aKaIKg;$P{Ro`wp?Ai!z4nud z<&Ec6+S@mFy}G|~Be%NkmZhNz$9o5rgZ~ovPwqZ{ct;r6KG`#WHk2^_4T|SKy!*(D ziz~?g6GI8h{||ao;r&`H>hHv>VdQ1MU#_}Jt+JEJ_{D=0EzmH@8wYt*j_v*_3 z&}8yE)aBp5n0>N!{*LSN`|JPq#q7@k@4sBkJXJwekrwZ>ke!^6gbcAl4UH>;3GP+t zAcFBAz$hqCGUI_&Olzs+^Qk4;sSMRpnObvwiS_Z#!l$!CyD2M;iaqnea|ca#)l32bM{Vqufy~hxWqTG5FrMO{+R+w6@N(x+5SNDx%VquuQ(O5 zJm!?yO+@9vn_lAAV6WG2VN~%qBJT&e4n*6FYzAAE@Pzu7n|;vRow$9Auq0GKa&E&o z!!_XDlnZP!se83#JowCV$nET6^p@vq&7qfy{j10UN%9q;kqY61-b9r8JBWG-wqli` z3E~9=rgif01)*{j0DjzW9;oCbE`9#OBBeV>8zC;tvWPf&p|X!91o5_J1$6`zJaX`} zH`&3#QDKV2B|E!wl@PEE1d=(@vLeMjdPpPjV1~ZcTe;t4Nd`*i%w8J>3Y3LN1N(`| z36aIFAe1zP!b#+1qc%nR2Z_lM5O%NJsID6woAqZ7s)_ik z)B}=`ujE{e4Ltlsstc{D$t97Cl!?d{Vu84~#f9_5GvE*tL+|wDz(Xizk(tbtH0#w` z!wBTiu@lkI^AyweAhhXMi{R9-6Qkkc%s4QuSLTa!67rP?gqrX9O1qK=C|{8PO6he& zF4~BKPldg3N^IfZGp}O4h9Sg{w*M5SmJYvHw$|Q`%U5p}sxwTmzFtVKo+q!_HeWOT z#NlX?v_?Lywvk&Y%pS_Pd%GD9_@X1Gznl>eRro{mOOl8no&@jvqi&0b;{$~B_aW&~ z!3(({DumefL44-4Wy*;X;iNxP*-6R#l6bx$1$~k|DZd4@jo=YOnEi3LWn2*ILf{B~ zs0xkYi@-beIrXGQ!vWTW^7|8SOGA-@AQA@S_krjU=}HWNr^>?T07*a*KO+Ky(PBlo zXu#R3F-X{zY>s&iQl(SnQg_s*Tf2%KlUF2k5O@x!)e6@_&Ji6eeq6ob!hqpSnKtwv zr!womJ#}^YtaW*>0xh4`KiNjROqIjoAW1XyL`!X&_AGtb$Z^vO~) z2G|5kZ4=qRfj-!y*l=$4 zy@pvZVH}$^1S+B!Mwh5-83oEM4!xIYFb===Rrz2Ji)7F<3KmHvm@~aUMeQ$Lj z4PpMwZexL5E~HbR!K|JheP*}QKeOBD=tk%gVkUc-1&#!OFDcI21k+TvNaH>-1*pQD z1_#)822l}{O+XVr4;AVK zOP5hLe|=m^;aqFDn3KG!+9-U--qMr1 zrume5_iiTBrck@}URAy6_fow%yQ*6@s_Lm8P>CYj0HRO$qA4gCv z8{iws*_8(eXhQm44V*r)>c{s;a1`uQysXU=4>$YS=4EP&!I-zfZqYf!s7cZhxdt>t z7;^Mte|rOG+8~f8(AP6=6!siXD9NCSTJvlrXQKTkqX#26si!KatJnuOHD74lA4*PzeJhhp&MWCLROE!>kcEZ84s^cDy?xodQvAy?Jk)? zvDv;Bv$B1+JpFa!LBHAG6igFXJM7r#7ullES55+P4cd+YTcOHv#nZHMznwI9n^eog zJHzSwTP~bYD{5_^`c{s#(RD)lre>rH=fgw<{G}wWZY%8cu~7L&ZO;N`+` z(d>C%9saP34sC2%5?V3Vy@fBO(!s(eOM%$&*JQ5s9k@sI~C;X=BMpMP3M79m-31Pp@kB=)TS<4KyKLU{pMSl^i*?OT0U7f@xKz8Q|e)q?ouID2nVI;CEtu zVOPk`eJZbQH2NNJB7>IduIW=lbS!2Zbpnw{gfUEYu}Y2JOAIy7P%2m!6~D zW+MtLW`Q^PyxUW#J33dom*{od1Eq<;OW1x|g#?racXkk1eKXFuKBLrUtYnG@RET~8 zn=HL{sJxN;n6$%3)1I_i-`oJN#kzE@d-Qx~UmkQiJRB}aeQGxuyjCGO(DT}h{CW@*#$HHN9s?D22xDAUXLQ9_SyDibKAt8AY^b558p@7`uO#E~XhhWYFYL=#1rGeb`w%+LYdchkW{ z%=!k$LZzRpf+W&>@MY81kMlN##S7{=X|>w+`fM7SEddyczJfS%2I|sQ%0^07fbO{5 zX$D@t8IL;&%nj@brc~EHtKZzrP)`?s9-dyVXS2Io$MP4^vVgtQEuh^{%pNaUwlaSP z%~8t3oHL}}(6=w#;P3r58FE-v8o>;Ojycffg59V5Q=T08Mk>o6HO?naA_`3cM6>7y^orh0vx@5LFgnr?QYn_B?(9k?Ug&1mYP;aec zqd0n$Sge5h2@HZM*wplzO8l%s3tMlYEam8;>rF0NoRhot*-JeQeAX?Z#ch7r($h3) z*37b+ns2L^&R|%PE}l+lUN+@E-Bhpwf;~fAyTMH;Y&F%NR7ijc3iMmvl2sK`Ues>! zs@`U>dHr&_a3;3g*zS~8LJN*eT*|#{aLOq!&U1fe0}Untq57iiiUc|F_+4vitBpOLIrReWq;M042| zi)$pr>8Pe>QASB#i)(gh5{(k0z!Q#?MQY8)-Vo0fVz12ZJ!GuVG|3p5JN z{D1>~l8im4*y%I^7<9M|aF>b#RG93FOFsyQJLmVnMjQxW0Rb?(eI;h>NhOFPsi98Q zSJN?CpIAv~WW^48>8=l~NDFeMf^o_?zM75@aJBW+HYCXgB2+V2M!e!icL5W91*s&g zv1hA)A55y^5$C{ePKvM$t!W$@#H2-7vM!oxw*7#=9Gg z$_n6Fv90x)Qm2lhB>{@Zp@LYJGdkFKl$HoB@8?cNIP)2i`0zw-EU|8Vrr^)*X`@6d zjBAhBU{oMy>k8=nSw#3`==30*ArczeH~<&`cFGaU)9RtbcN)8GPRP^L)gz-R)aS2q z=-qZ;&VJ?ysLA;_T+k>q#;R9MOjnzSq`?8X*nAGokmY#dv2Rig_DLo3dJ99P!u4Mf zvYP6N)y}S&d^dR)J7Ubn1U=mDY8wPs^2#itT2IzeP?1|E3Nm;A5lT(Dp>a4_2uB&F zB;14+nx!KjY6&A18w#yGk7PS(VGc&--h>YzTxB&7+j4fY!Lg>^7jg-9IYkMb|6>BFVbU6JV_9@4;&30)rNs*E86u<9X2PY$8nk2uMnD=rllL+c`uN-Jur;Y^+05?XdV{Sf=Z>CS?z57ayXS5BK0@dB22_%asfDntP4>6d6nobd zeUjv~Cp`6Y81#py0I%q0MjZy)&*?Lx&IEY_0|;)MXF3E+Sc>dAGfg!a)MvucOFpF5 zqFCSC-6lwxdCjlV2WsPUDPvMgMPC(qp!tk}^IM?w>0Zi@uI6DH%2OdACVRCqovpUY z(&c1(JcjDHjTBMpc6={HM&n+OZUx3#ZU^eKq%z`k$%co_L&EM`zNWp^Nv70~T)qQ%sUrczRb#k+Rbr|^7U&DU+Ec`eC~s+KJ{wxxaKTHRl> zIN$dd;AkP-ya!%yO*YUDUF}J0Z%^ z$ezuFDvzZ35WM{7vV;=X36-zGXHat`k(n0@FWBGLDviF`b5UN-bh5EwDXh8MVA;wqYBhmFLl{M?fr`}^6KE$qx( z7D(U#SXfEY!@1L(fHe!YB+(t3-gllVZt%nQF%5Rbxd6H>Mown8M3t0?pN&3C8_Ija zcP#jTh3mDN-1ct?yRWga`s#VI;ylK>wb+NzNo(_=QP0Q3EgfB(J90(5%pOvX zVZYqnDt!FPOQN!af!MG&;x1!EI=cCiP%&?0Jb%U(JEpy4hySL}<)HrdmNkW<-olIi z&`4%^ttTm@vhf7N z&+>r=l6?3Th=E*u z)X&uX#H%j)^*}5W`e4)}?)`q3#G_~W(_7B&pgwHM=|S8kl)(sv#0Vd{QiA^2@G$Mr z)bRA8_apLA=uJ(Tz0HY=lD4ujT=bTxF7@;WB!tY`#cMz*HkS8<;+`$zL{YB}8k;^o zk_B(@M5}szV)&=IAP7F0*V*%jEt6wmI62uIXkz!UO?wKo3{U)3K$s}dBqM$HyE&w zH+(K1hAPXMtcX_;*cT9bJY5+%*-F?x! zexkpBmA@&(0@qxqs*=XpU@P0Wf7S;{MD~uQKs|0ENbW+k0y@ulM2#HP4 zffw0;1KZ`s27z?gY=y1qGui~C0%ho$AX8Z6PLcPKN882z8<=YL4$%#5FS z`9JID41bgcaB=-k!2Vqg|7W~&Wl=F1wSS|Z|K=U~8v*_QM&r<*^Ob+1iT}nDH~wUa z|HcsiE$Qg^cgQ4$e_+u6{`$WyC;!*_@LLP$=~c!_q{bDP=zJPn6gx@iqc&0k9NGKA8d}{3($r+h>}w{t}TpnehiV6`N3A_Hy?`g%~lsEU}WOQM-v*TSkp` zyHWb`H7ZF4@(fAx>KZF!d`kNyCPusn7BklXel~ z>CoFA*Jgfe5Ro|kt}-AY6D5=HW8nirnB#oksm3N;v!^vnSi;(%sJpskY1Za2m{4p} zMU&N}PSC#>9*+^opaa)4>Ccs%0Bh$YObZ1OtD>pv!0XC@l9UQq&K#4Gtf{Pt8}M9K zl+26dRq|+>gKfI?$)ur+t8|?B6!Fo`e^KPCS1MxpI=x~BdFPE6s2lZ*8KiVgv3m-| zahV2+va7a6fC_Z9KT@x=OT1ceiJl5^wCAT@jqkE5(?Oia=P9#X2s_kG!VS;O-of-X zw_M0c?B~RK$o@GWN=2OrOC%)+F0Br~msQjbd)v?Dd%LhjdLilE<=2+ef(Sodg#O*` zj;`-I?lOQ+5*}Y&4X#t7cv8_iQkeinSNt0Ml)b6TeJZA0SG>}Lz#Z~YW4H3&U?og* z=1#7gx#*%F&##)Z4$Y5YjLCu7p{Ym>DgA8eh>EvqY&4J(7)eE<_KH6fY&=?%{dTHqWb_msaBgNEyqr{QAxbldQDBXe0xMrg|ENmDnH;Qzw~j zmj}wSd(~pLel}-lFTuX~WX4Rdg40BmfjS{x<368iYvhe9A0ipHjoBe60|;trej6dS zRfBjpVH-?46KwN!}w{(-xbw!4(`_W=@C*ITDh?$A>ny zdEUUzAA;yF14XHG`w?&D>%gK^;3xQ>YZOC}mhz$d)h8+JM8rZdge(_v;3;W}QX8EIL-!2DO!D^Ql9;@Y#qFE1PkvF*G} zYPGhfJKoOM#-_8tX!4={v6=3ssKc0>ahGNY;S2=_4$iYnrs;#a7Z8v47#u_ADoGwC z9?zV2b%YhShjy6>mJVf3A?2)+Q|e2cOMcapsw-BYZ8-Wyj+gD*@CsK&^lDJ_rR_Q5 zrqwlU9Q?Ac_+@~U;53b+)JDu|V`d8G5>i3(Jj^93uqeb=vFicoiC#weAzZ6A6JB|i zHJ)oc3v4r7vVfSuxo@PinbfIVo7DO1We$$rR!hQMP#&H^cD-HR>v1-m!Y>_$JS#}| zQJa2?+$*czz4s3*>%MQTwn(Gviby+&MFtWsY*!>TDr>=)nP|hex`e}2%KjvJK(qJ1t$Z?*OBaaw~x?@@pTWGgdwXW{l zQ7&rhdd@~Sp)e#i2o_yh*Baqsm)dm_0f~S!I7QnnZu6S(YPa7X7clGY`?&UNE78Y+ zhrEuc9IEiN2J0Ohu3B10V}_mwBHQxwPl7W|couv^Z8WyLc7TGcyPWw59}y>{d?9n4cXs z{hxp(|Cq>&(@N0(TfC(5?|{kw1zz&^3H{$6k^Z6Mf#DBB`saU6!BNk_)yDAmb0obW zt%#|GgP|R*h=s0$p^%}zwSgh6q@k6ug9#q{Z-#aGzp+9`sD8Ggt1Qs?SJDJ*$)lh# zYguYW3(sZSvSx#se329C4;Y%^GZ!Rupp;m`l!NdE7)MZ3WC8-#l+Vi+8Jxxona=i| z7TT2@)5H3NOO8=b5`H}CI09;sOr(EcO_*x8?{~bcUsz3sR-+54s;NcX-`%P0H?A?u zVx#8BKuit1$f%WsP8&-`!5Nc+>zDi2`1voEGs@lD_ut&qE`oieZdaXRa*}xT-OTp} zya)!g_kx*U6%&*JDvOc^m22*v9v}ZyO^c2#jtrS6FPcnY6h)88Jx!ByD~p|@zZwyH z%(A42V8NG0uCiAFDN_{JDi=quSSXI?#}9i=qEVKysI`YlZBVN5|VSu!mvOP9_dn6x7DW5|#Pmx%(6rm5C)zFuMUOFS* z|3jrTE}lMQ`-(#;UcN}FbeE9%nM{uB9j78#!W8Ghh3|QgGa1Hf%rs-9iGB4o`akpG1GT{Cl3K( zzL4@LZtjX6<(JinkdmZ}Uc5+x0f&lEe{Pn1uA_^9FG+vBin%&7o=$~?ylL+GIEj*8 znpwiT_;hLNWgjXJg3tn&cUAo3P{Y@-dO4pkM8(neMiEeIvG6OgP_18O3ZO3)>MfQM zLkv=n$Bm!O=?g9`6s%2Bw%*1)08zt?>7ZwX<*DHAzR3b@(&dDSh#P%aJsD^+K=2a5 zC4E48z}te7gd_-*;5vF7^dVp*uVAEl$TjhocqEAUeGGaa+md5Mn!(KeyjLXK;y`d= z!D{}P@ZvxSVIj+XY(0_H1SoJ--{}RxWduaXf@Au=`{D<}-O!(aVN&ho&P$d-`WZo) zHQv`+)p=Rv)ijepCOXE@7=S!Ac*M1(U1z6)MxlF{1ouY6tP=n9ZqzVdd=5QLn7z-u zFSvIOlE!>))Q#+A>ct3>!OdjUy9{o>^?2_4=4LQER799Xzl&}y(vOCgCs_XJbyJIE zk8Bi;K*d>wjAGZGx>2T!4-#x+wm>yY@s49QBvwjbCnl#7CsnY6LjPqLh;hH!?xr&O zO%)Jx7(-A^qy?W;*vBYa&~8?Dt4|Qqn%G4E&K{n9c%#(l9XX7w}WCV_yop9Z5 zfB|8|A44rcsGC1A0reXb;<{+vcE@R(LBLwA9?Fl#FB&h*?g7$y%BE}jD*l{A&kx2>NeLNt*A>FQR^ ztqF#C7~(^#9cR{LN7-L!NL>3@kvb$WXjQL{Ti_q1Km0zwq?f3c=;1{L%>daUBAgrr z^QMNf3VnCy%N(f>mjYKF%$p!ak`)pymzpVARceep`DO^(X3VxLHos3LHGZFZ!`vRH5NIKic)^q2h;J=mz(5LrTT}@uS-eg zm9mFe3%f)-@*`Mv5osbjQEn5C+aVH-1>Dp5GMzO`rV1IOb|6o3aGax*v9SOq9L2VI zt(dz2)pxo~@E8jVQtzYlHgC(>6txJ8ml(mpCi^+=s!2_xV$BgwoDwwIZVT7N{%Yi} zJ{N7n1f&kpK1?==&NkzLgu{ckFZ#`B6nJcN8q?O!l;w|bRM!_hdLYwr=~J>yZN>~! zbUVY7-(l-#CryYjb#GSNU8`g=nVowcmz}e2J?tM;7V3Fpf=Ic-cZ83*25CN9V6%`R z{BZ`P?C9f#D_d)FhY=O}7KFLHk9NhrkIsZNHjPpjRVi3=#lmiV>%=ubY>@mMl)(9k^)DQpFXd0J}A@WuqUyjU(rJklrXXMG2U!!-ydZk#a2Uxyt-vsKr zjt*)@Mluk3zy8{@QpS1 z^RF@u-ZUx5Fc+I{{3eVAM$OfUmD|E(>w^sY{*`bCJJBk<&(LL8GH%zog9Ljd5a+e? z8C`XZ2Ffo$HX)lEj#=+Km$Xz|Yp?5M_c2G%vy25)6LCrZG+hEsRKIFkLQy8r@vpCt zRBa$ETVRa3_yk>FBYOJ)|I`4%%t|E6ASC^jos9np?qf(TWV5HS?XHT8u)ziZToRV& z((yhQYd{JBvyV*H*N~ra_~96xA9i;iwMqZtXP+06tqpr)syY$w;r8h>DkqfeDFryki(6URK9zeQeOfvtBIo zm=6<(s1jc1iPxje{kSa^L)(@bKJCHCJ6jMEQT}q5I~$PaoojW~Vv0;$F;|f#DTfK2=HgMp|x!@a}-V|UY=@PjfomXj#10|c9co_bn}M`0c{?>n)z~a_X0dLpl)lwWo^C3 zjgJrKNaKwg_TMWnjar*K=JUd}0SAU~W8J@tN7`xEd!-bTRN@C%ezT-=ID99(0PM|i z2(^0MT0a(AKbn`wVRp~ zQBj9KV$9R^&NTTPx@2BMPt=_n z+&1gL@%&g?xO<~*1}YLE!5}6g<;n>56^_vha5Hm>9pv=g@$HIzeYn_-rBYd=rJA8D zS+%7BgOR6(qka4Gs0`cqV*MAGhE*lwbHpVQqqe#c6jG)Z7giVWygU}1ta`A2?Jkw8 z?k*%SZEc*g3x&fMMO1B`u&}KTngO!R;`(w3pZX5P8_{)IJ*_V{F3Dk1>*HZ+uIB`< z>T1fu^O-a1z|rlPaHb)`T69$^A1!;i{d-}B%nhhJYFbUGz{)+lY4SJ^$MBTsoAGGL z*e0{(Tb!WDluN@dA%U?&m%t&AXP~tP2+du9%ZCVRvC2uLx?WWolChKH37>?%FPHi& z(m!yoV@!26`ut^9*EK)eyz1R%wAjFa3!XFuR|-`A1me{R8F3+nabRJ31*u9TrZ^3<%Ki5N5~WdR~$t zQI)*G{vmpk1w|RvpsJ##s%m+Y!e;d$nW&>@n=AGSHS9{+ayvX|_co)SQMJQ_MplKZ z%iDF11U5uV$^5`1FVQfjXjb*XP1ZWs)9GAFTY4S|@v%QZxll$gF@mB%#c6f^lVkVP z1G!C*5PrMcvNQrPgxj*^Fo6o>b&!~t3Q=K1#n^hKXsW_!>l9~|m-#eh@~ywp^r0q? zuaGLMS(SgDAe9!PRb!fL%%_7$Y^?3_BT0>F!Vb0`YRvanZERBGsqwd43_HHOZvKV) z>z|$e{%R&1*MslTgfS1L`&>E*FTRYD!V|TIwARP=`BhY!GJB%cvag6?JeXLA#9G|z z)8RP9Vl8zS5)F@f3~={H=4O&$E&DT9grFJ&Ot_H|dU8d5(0$9hSxgK1()CyyL#!18%)lSwl{52=WHN7dW^i<8K1ixHrs2ewm4qDx^wHH zQsZa0_Zkxo1%Q8_<>Yq?ctujU@(dZ)B&u@S8`%IdAP!Fejvgv>wy2KAb0^!5&QG9g zF9N=NIsS0~tPJ(#<3JY*=Bss&P~otHM{^EQU2uTNQ&dOBY_tVTt%wx_lf;DUA`q6A zy~9~a{wUV`+kQ;%Kzc2eAV0qoN-H%nfjuJXNdE#+da$`vd!JU}_dqNWE!W3hRAa#; zGL|7y6gObIIEV&oWVT%8Vw>&RkuMcsD7{-du-P>*7Y zm+srdc7)e)M5w$(zr;?ZU^D6NntkaN&&VdWi_1^bPhWdpcQjEt-g`TVJe@mY+~-ZG z7*SA9Cur$IBKk&X`7e<7P*3-+b)?G1mNe8_iWZ80gvb&e0Fez=+|!U5gKS-77<41i zx-?EeOnm7V>Nm~H!`zjr7P%JE@4eEug_hf4!g#Mqz;j{nUh?N@gr}xM2JlCwLt9RU zKzJvQN)r`*#$ej6bXUH=#crRV${^z zw80m1rUSm4j zc(t*Ty#ib+EKJ@)LPDk+p0|~%sO`2r7b0(`_n^)ZmHpW1rNwZ2rT7xbNyABsC z=z-JtaMxV|mCD0>xqfSFB@a`z_xv@ND{^FFczB|C%tYL9(p<(keV;7)!=dUh3_1xF zi=JIKsG%C_#g)aFE}z6Dk6+G&?yyhF1mgoZ7CV?`l*LZ5xu(3WDcfYxY5_FRG}ETj zz7zMo0r51<2^Gb*Uy=Pjs)NId2zHXL;iM*Sxf=i^!b74*N97mbLvxp>9UC_HQ{w*b8*HI&ia`l$|yz(=hiO7#l}K9T#NGyPnZ+mDs?o zO&;{DiI@`NJjKduKln+%(>*{wINVrwe9z;|R7f0`yI(!=PjPGtuPP&yf%yc4t}I_U zRl)Urd?mcY{`PN$&fi6@--d@wY;;V22%YqQl;ZwpLZ_6Xl)Q-4KMI|HGiv?6w*2YgCAvS|BG=V^S^6vu&4d4zu`|&BDcSjD(Qb4ZGWnae_8v# z8Fl~HrOH1y#{XrS`&mc(n^ak;+)_#qEU^52&Y?j>SkndU9?c&cyhnv20$+YwOdK=R%G zIsLr!VZ-ym>!DSH5-dsEUm)iaMg!v~5u1f%6A$}_5jbO^f22mPL~V!!VL&&8?l;=) zgpD-Wd;7Z^i4m3HDYK}Kmp~Wpdk>yr!N>9}+3Bn!>Jf59EZKB4$rZ8)7WOogh< zBz5prq`Sye6g?(2>Ih?QaY}yH;b0I>$0l0X#>f{9M_082$-&NM5#TJ-shP~?={)_p zHOKN5JKR?s5z5x|=sPo)?W*y^<<7<5>y8v+^H&GW##-{(>K3x=*!Dt;zulV}C=aGc z1~Lt*<>{+TzPXhNe;x_!pB4PD&F1{ggpx3J#%MoNLF0&mfV1)lJu?w2m#!r1x!HZe zi{oP5iSrT%8h0^}77~IBRm^?DMI?iRCa>>2UOV~23P>+t!2IEaf$)^U!a{J{qUA&c z!Hb^&MjJhPcu7e-5xAR>kiKsOv8sHJpI}BfJqG&FU;-2b1uz|g)MW8+61`wqg79Ps z$xlUdyN^qc17#%&4DT5+6G#vWPqB|klA;GVtgSq`)a0DGU@=4+yPfp5(owF(LZyXb zH~u0fb5HqNXKu6P!~x3ltl%~&J8F4;+%e)rjn!{;wqx28_QCTQ=k#5Sw`Fs}YxAzr z1?qC?{Hkt{Hq(=PJ~JnilbbUId+ZZXrDbyH(mg<#jSCCZQR=3t0)|1=z&BE(nDMPVe**0QmKZ+1I6K%7YoToqE`La? zPpjk?Xzj5MJSKqk=D@c=W!g0U{`nF%8VDdElBUzZivu@<1jXG;R9UK7R4NC?6u#I;^QA{>XefPt$T-SslwVL$t* zR0*3(c4UO+{q31Bn2e|}flx-b_?#!6ogNCMP@7~&%wgk~Gx^!dD?o+x*0V8gw z)aK8kkoB&q6gGY@i_7%*wim=PC3GYk8GFCzxN=LINn?L1V+aVW0S+EF&1lGa9V(9_ zec2v>6wdAzimsNfKu%Hm{w0)bE_@|kOd!jtG$=LZhz>X@M`{^52|!~C^yD2@Hxq)M z&{LLoZ<-zg?b72KvI%ha1`?xdp!M~B%6qBUlrgB2(q z%2r6}ZpTL%mHpVDcVX2emB+pctXIsIS68o;#m%a=z_{%%s_O(cry@olAzTRHksJnL zZGT55HKhed2EK22+r1OMG_od~x7&-sOg%#`jAy=TWbzeenu?e`)LR4#{goakQoARb zY}^?FeqYl7KjB}>iw^vr)j!)pDf65U6D>wopPj5SIgTR?Pkd{ZJv}mgF<*dzD?iMF zHljKrVQA%14Ui5K?HvlfQP|`p<8#y41=5EfZg-%mVm0j!AygAs(qXx)fl%KRH`j55 z8mthN^=FN{mfW7n0+tS+9XLAnqctt+)tyfq}yZL2c43AUk6 zFAU=sZ$QYZACNA+ipddRmjZ(HS3ln2V@%lG45@OX5n^_K06?3pT%z`m0Kjz|x_^w6 z?cuP*WFL0{1l1&wqj4Z;MvF&C&IIlfeSTKKSzHp#4y3ItRNt&T)(L1*GbNxiPB}%^ zvGwQ>P=R2}ZK)?ns#OyqQFRDuSy(hTz1>!S3Lf7)VW|vF?-vm78$R`?IaQlG1EZd> zx$R(1+b>@Z%VU@eS9CB?^Cr0j`?fM1Bj7l(nQZu1Wqd`aNN4o%a44#NO$1}`KWkf-9QY(?f#gs?izcB?Z}q~Ce$l< z{kkDP6D&-~2P)Npq+L<$P+ptiGp9q=&4rq)8(NOhl8dRxnhdgmh^kT}juea@MlxGx z&uW;kuUz9ScY^i{+)7VXe1x)AVn&S#cOhoXALeM@CfoMXYoeohK|Niisa;j5wZ4t1 zlc+sbt8r5~wTF6F8SSlb+8YKR2Zz0GRz-l!qbjr=-cwcbR=m?TSj1sfRkn8QOhfY~ zX5fTLUhXC@aY99Zok&ycn!vfXbbD_*4_TBg(TbHJ=Yg#`zwkF16w>qu})~3CIAF@2o$3~re98h|oBdU{h zHjl=!5PX3W%R zL-H)=(-czJNwBiFv1RB9xDC~$>A{e8IMct)c4xmHTqi-73_`ywHM}4=2cgQ)jMLUD z&5Y&T?WdL9!*JL?9c9qc7WADfq8cF`CO9iiry=bUD^HiNjsMcJJt!t55ODm|>nQLu zn5{XoMy~0YLBv4@1;CqIbD!d#OGnp6FYI1!VDc9%i&YPgu=ETw{8-f#R_qNxpYZbg zX}KmaI?7M3g>YuDlUO-C6!LqVJ(`~_6e*uEJ%u4$0ND`(F=PTWO*vN_GGF4~ot`VE z%@i+_rr9(&F!%&wAoF|Kju#?|g{>b4ADs%8WpPB7w+kxWc0&bsozv|dOU1?Xk*MQ_ zbEggVTIQSSlRJA!y#WQ6R*@FvKZe!b=Y~bXdkD{!J*I1YZ?&3h6Z_jqI*Det2P8wA z-3gpb9f!8ytZJB9te(UL@lb_8}N6*$>`XrpZYY?@(nIStPFliWMe>;5`5Lq+o|?7@b4>XY~!mFp$~FE0y>E9xxG1F8(I1m$CzwUrQz8=47f-Ud^5 z=BPLuohYqCYCEkNzX^8Q+t^}X9olwSU_otY5q%K>MuKDIoQf4uH#~Aog{-a*#Didd zR6coE?TFNtUC?~I!Su(q9#s0S;yZv|?2rPNW171~bE zTPq z37;9?PiPf4o8xn;6v&Uiu=4XRvP^~wC%6`VW(#DJTd?HH`AQj2(L(o@MP&GMI_IJ&Y~De@Ea^oX=?=X9#s zW*pFvveh%+M(ksmKw`+gZuI2&HD0Gng43Elc#XLt1(Sa3Rsvz04OAes`od{ojl&6z zXjZKoh6UzWJVmtJPV2bv%9}Gk9-4jL(b2EQKHkGrHJINf2g>=>|0>}X0$C@YRLW{S zKDk@_YrKHnFhCd>Sorv*;jUHM=JqViT)CQGu}`~qg4K55IvImLz|ii%18esFY2Htz zvLr=6f(B9`kBXm7sSl^~_Nsz$aw2nbl6~8zPHQPLqS{>xpFe1DmoV~#(%z{cM2wEP zarDOvQD~3fH48!jB+EYcGRZXWQ%a-&EqO~}zWK6eH@WSnpk~~LfzbIU_3d8Af&Ug#?pK(PzT$*7S(>4YX zFrq_{VbBJnrI2B}i{(0%N~;r9+?Ob#jPSOa;;CN5Z$;=;#&Bw(pzt+(jH5)@NgOFn zxrgJs%CYPZ&&_4et89ipoqvGd;;u%nsU1k-p*B0Y!a;ZAmb`mpgqS0`g{ALAJp$Nnlw{PIh72XVMVKq`i~0FEYO2C@wb4dHXJVkg%EDOAu!gad(x#=iSsG4}%))jc zk@{)PsExR_zB(T+2o%agW?9WgRa|_s(V)=LkaQc(Dk zAABD_QtW>TBiSp+ZpJ;|5Y@164nZDXX<2%dx+G13;uJ$be*QF-ITq2_svKP$u3d(x zWyX{%RZR{__QqstrPj3?i0ZngJZJ2po+hzBYmbHo*os(cVzlyb>c7}UN>83242<6g z;a81k*4YRc7>tJ~S!_&H1UzA7WW>c~D8)EZWwaY`B{_bbES{5r<>b+DylcqQ;_mr^ zlc|ekZtLmbx2R~+g{3BjM)<*K(q(&9k~{N+8s>%(BF_m*p(6KK4q-{e4>=j%kpBYG zN;e62k z0@4Z!;^O}(;dn9W{ncnsE3Ip3NGs3!rxKdK+V1gKe`m~nTBz*o9Ry8u?eG{GXeD+3 z{5JzLGp&lLfrE*?1_TQo9p3-q_h0Y-*ZTeI`T3te16mM&)fbun*eCwc3i;P9;Xf|m z{Y!t1PnQxZS zX#U@yPiw&AP_lfsS}yBteS;Sx{XWySD(^mQ=l|4ybZDgy`|!syQLS<>ck}gX(LH`R zOL*GTPdDrL-LvLYi?lBlCNZk3D{IA|agzq3qAD{jJNj3p|Hn;hs`j(tx7a=FdZvvj z>-pktms{G6Q^g?%a6Z$LrL?Lnr8VFHN-728lhu$?0GU$z`;ZTLwuCb`Pk(g}=)&@ZsQrM%6}I>^Rs zx#`$hPH{3wyC*H(5@!QZ&GKi~ijLPq#=m=7fBo;rKR0VZ>cMoi`0-lay|}#m>4L** zdnZzRl(o@xza--ghgRRjWD~T0?V&M2)3=4DbGJW%*74}81*M*7(fAHxa33yRC`h@V zV=&jkRrjD7U%KeOv)~?3_qc>HCw*_xT#PV9fm0MXk{vwvaeeOk=eXoEUe-r?Uc9>g z?KP(>pRE==$OjGyzFF9ssLDiDhN;B452-2}@ z!G1|TkMPDBOcvV-fPy^z(kxJQi{(SjPeD3_SUJ4p(1ti!B5(ek3gPVM7mzdr^3|WVM>id1} z_RIN878Cxu-MqhB)Z6c#U%oA#|FyZ@-7dDPzjsCWLAmdrJlWrz@M&8wXQ}{YX6pW@ z@Xlf4c3HGC0OgPvrJv$vFY|bNF#-gUfvOyC<)bou7}J+Trm8A!o}@CR(vB}G1E+X> zE~=DrAmvu#$GS?%2^lFep@2* z-lp)J$Xuw>!6GV)*y~INpwnpsQVvP7Inp*^d*zfC?LhzIzUFZoCa=##t@(RR@M*^< z(FJ`Y?Z_lD03+XvZp!OJuMfO`QD-Y;-T;?*d@+BouB_-I9V_6z;e)lJy*5~0&R8S* z*ZClH#`dQD+0+KgX)aUVh;gYx5anDnDW^y3bJ3?Qz(l5TO9uBB4OP0!gp_lYw1Ex| zg#CgxypM342VM?g!*l&WgU|)Qr)?QT7jK-v62Q}Td@P_{EPqxZByyRzPL%UD3d})x z5q%B;0hQ?o-bqY!A#Kqi?En>pU!i_t9N~x-2!*4@&ee&J_YD5!uCD;cX@7Mh8at8djItZ?~PV*7bJw_;FEQul}nO uK`6?r&1P4iRf?;ke0j6n6xdtERXRL&yPI!!4VUoInJ|0w=;D_jXI}u*hsCx4 literal 0 HcmV?d00001 diff --git a/doc/salome/AddNetgenInSalome2.ps b/doc/salome/AddNetgenInSalome2.ps new file mode 100644 index 000000000..a81aa9658 --- /dev/null +++ b/doc/salome/AddNetgenInSalome2.ps @@ -0,0 +1,13935 @@ +%!PS-Adobe-3.0 +%%BoundingBox: 0 0 595 842 +%%Creator: OpenOffice.org 1.0.2 +%%For: nadir +%%CreationDate: Tue Dec 9 10:49:18 2003 +%%Title: Proc?dure de rajout de DATA dans le produit SalomePro +%%LanguageLevel: 2 +%%DocumentData: Clean7Bit +%%Pages: (atend) +%%PageOrder: Ascend +%%EndComments +%%BeginProlog +/ISO1252Encoding [ +/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle +/parenleft /parenright /asterisk /plus /comma /hyphen /period /slash +/zero /one /two /three /four /five /six /seven +/eight /nine /colon /semicolon /less /equal /greater /question +/at /A /B /C /D /E /F /G +/H /I /J /K /L /M /N /O +/P /Q /R /S /T /U /V /W +/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore +/grave /a /b /c /d /e /f /g +/h /i /j /k /l /m /n /o +/p /q /r /s /t /u /v /w +/x /y /z /braceleft /bar /braceright /asciitilde /unused +/Euro /unused /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl +/circumflex /perthousand /Scaron /guilsinglleft /OE /unused /Zcaron /unused +/unused /quoteleft /quoteright /quotedblleft /quotedblright /bullet /endash /emdash +/tilde /trademark /scaron /guilsinglright /oe /unused /zcaron /Ydieresis +/space /exclamdown /cent /sterling /currency /yen /brokenbar /section +/dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron +/degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered +/cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown +/Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla +/Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis +/Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply +/Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls +/agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla +/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis +/eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide +/oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis] def + +/psp_definefont { exch dup findfont dup length dict begin { 1 index /FID ne +{ def } { pop pop } ifelse } forall /Encoding 3 -1 roll def +currentdict end exch pop definefont pop } def + +/pathdict dup 8 dict def load begin +/rcmd { { currentfile 1 string readstring pop 0 get dup 32 gt { exit } +{ pop } ifelse } loop dup 126 eq { pop exit } if 65 sub dup 16#3 and 1 +add exch dup 16#C and -2 bitshift 16#3 and 1 add exch 16#10 and 16#10 +eq 3 1 roll exch } def +/rhex { dup 1 sub exch currentfile exch string readhexstring pop dup 0 +get dup 16#80 and 16#80 eq dup 3 1 roll { 16#7f and } if 2 index 0 3 +-1 roll put 3 1 roll 0 0 1 5 -1 roll { 2 index exch get add 256 mul } +for 256 div exch pop exch { neg } if } def +/xcmd { rcmd exch rhex exch rhex exch 5 -1 roll add exch 4 -1 roll add +1 index 1 index 5 -1 roll { moveto } { lineto } ifelse } def end +/readpath { 0 0 pathdict begin { xcmd } loop end pop pop } def + +systemdict /languagelevel known not { +/xshow { exch dup length 0 1 3 -1 roll 1 sub { dup 3 index exch get +exch 2 index exch get 1 string dup 0 4 -1 roll put currentpoint 3 -1 +roll show moveto 0 rmoveto } for pop pop } def +/rectangle { 4 -2 roll moveto 1 index 0 rlineto 0 exch rlineto neg 0 +rlineto closepath } def +/rectfill { rectangle fill } def +/rectstroke { rectangle stroke } def } if + +/psp_lzwfilter { currentfile /ASCII85Decode filter /LZWDecode filter } def +/psp_ascii85filter { currentfile /ASCII85Decode filter } def +/psp_lzwstring { psp_lzwfilter 1024 string readstring } def +/psp_ascii85string { psp_ascii85filter 1024 string readstring } def +/psp_imagedict { +/psp_bitspercomponent { 3 eq { 1 }{ 8 } ifelse } def +/psp_decodearray { [ [0 1 0 1 0 1] [0 255] [0 1] [0 255] ] exch get } +def 7 dict dup +/ImageType 1 put dup +/Width 7 -1 roll put dup +/Height 5 index put dup +/BitsPerComponent 4 index psp_bitspercomponent put dup +/Decode 5 -1 roll psp_decodearray put dup +/ImageMatrix [1 0 0 1 0 0] dup 5 8 -1 roll put put dup +/DataSource 4 -1 roll 1 eq { psp_lzwfilter } { psp_ascii85filter } ifelse put +} def +%%EndProlog +%%Page: 0 0 +%%PageBoundingBox: 18 18 577 824 +%%BeginSetup +% +%%BeginFeature: *PageSize A4 +<> setpagedevice +%%EndFeature +%%EndSetup +%%BeginPageSetup +% +gsave +[0.24 0 0 -0.24 18 824] concat +gsave +%%EndPageSetup +%%BeginResource: font NimbusMonL-Regu +%!PS-AdobeFont-1.0: NimbusMonL-Regu 1.05 +%%CreationDate: Wed Dec 22 1999 +% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development +% (URW)++,Copyright 1999 by (URW)++ Design & Development +% See the file PUBLIC (Aladdin Free Public License) for license conditions. +% As a special exception, permission is granted to include this font +% program in a Postscript or PDF file that consists of a document that +% contains text to be displayed or printed using this font, regardless +% of the conditions or license applying to the document itself. +12 dict begin +/FontInfo 10 dict dup begin +/version (1.05) readonly def +/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def +/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def +/FullName (Nimbus Mono L Regular) readonly def +/FamilyName (Nimbus Mono L) readonly def +/Weight (Regular) readonly def +/ItalicAngle 0.0 def +/isFixedPitch false def +/UnderlinePosition -100 def +/UnderlineThickness 50 def +end readonly def +/FontName /NimbusMonL-Regu def +/PaintType 0 def +/WMode 0 def +/FontBBox {-12 -237 650 811} readonly def +/FontType 1 def +/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def +/Encoding StandardEncoding def +/UniqueID 5020945 def +currentdict end +currentfile eexec +E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89 +699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641 +2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2 +5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF +9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A2261C63C769D2F4B60FA2C438AD7D199D8E4 +5F7E7C9A605C8CA14E21FCD81C9A515FB8DB6F99604534D06EA9D87FE0FAA852899C9D0595C7A97E +6C55F79FAC45CD38E87B10D210CE7501E88C8FCD3444354365FB893A12F596AE2C1E70D5819EE0D0 +87D10BF8DA96F3DABD5405D28C4228C6C31BA4052464859640933FEEFD8071C0C84CDD829A9B1D0B +A01F25A4D50EE2EA2B45160CA6333B2D2800306ED2BEFDFE155E9D9F9342EB8D5B0ADBF2460CCC98 +643FB1287CCD28ABA7B5CAB92EC39EE2E918990372B16F8487EBA30EAE88708B6CF33B6C015D8096 +C7CFE2F139F52052E3925C0D50FD64CE68236D59CB83EF56BFC584150EC38065059F3308AD6F9A99 +F83EF4E6CB13855C8175E31417D190D036B387D3952344A950F4D8C7781B307A094DF1ECAEE4D2C2 +FD747BC6F7F9C6BD0E90C19294F96C8C5CFE88FB34C477574A1B1630B8CC591529E59B20794DA32E +61DECDA8ABBD1AE956CF74012AA01D42EE01E861B0AA6897C864788AE59DEF43C493246FDB1ACA55 +4C12594BC7B33657A9ECC9E3D1472EF826073F632BE540C35FF6FB40566773F3BB2204D3A579A08C +CBC844C14B18C350F003B9DA23A570C362D6003893CA32F86F59B829C78EE3188B6E3F7FA81D7F62 +2825C639638DFB78B7AF1F500F5B450FA54DBFA5CBA277C794ECE93275A3DE0B452FDC8DDC2993BA +A42F28A636008CDCB03EBF71BDCAF35019778993443F88412AD2AD0D7155A3944606463266322DBC +0244B07DA1E9C27A27B59664E8566D7A54CC03E995AAD008B0A17E2C3EF61F720CE7F7788599C4E4 +4C709CD5C31B11107F16AD70B17B9AFE2E8CD922A7428DAC171427FFAF51067307FAB0ADB530E701 +FD22DA22C4CD3064067BD4F6089C4B2C87937DD426E4E9D2F60E608288BAC9056554D04947E69200 +61E379CF5E81BFD32FD37EFAC1F61CEBEE551B0851516471A7472C60DF89DAA9EB1DC5A67E479745 +3E69B9E22BAF4E3CCA4192D603295B018C4AB69D18DE52DFDF15E96B557F290A4B8C5B1E7A6CACA8 +1F2351B97ADFC36995ABA43803A6E5AC04A3C93495F6D38106B8B144449C07D1358210F9176E1565 +72363CFBDE576BFDF99FA329DD1346E83F79E06CF68250CA57A68931BC7F342AD295D0CBA17AA95B +B8EEB53EA6E8E660B814E9F857CECB14F44A43288B69A9E7908D55BF19E844359879D28CAEF1C38A +36420185D20DFB32C2E002202800E8EF3D67C5D50E919657CA958B538D537D503444865331D79BFC +40312068D72364503BD0CC84B5F30A74D8B5B6A26AF2DB764564FB65A6BA8F9051AE2B4EA458D46A +4569F30C6E77DC097356770362E6CF3F1661074778EBB44FF7D1E3B64FF75E77E11FE525BB121C65 +46CFD13300CA1F02D571B82A5825E6226D14FDCF27F06D87452A8B6C5DCA658535CEE2A795E58137 +D48E566B69D53A0C3B766E84C51EAA221C46999CC8065ADB2F129D5B630FAB1814C0C33B5AEA0EFB +B6E994D80941B53079AF96D90A0B924F9B0E319BED9836B8F9053F868363D3CA554CBB181863301F +8CB940872ED5FA7BD18CE39218B5AD8AC57D0F752D941076B1C64D99BE0DB86D7A6D96510D772EB2 +4C587F11779BD21CFE5BDE1F29C1EF9022B2B8BCD7F91153C845906722477829C40111D810480F3C +F62DE8DBA7FD86CD236E656618CAF6FC46827FBC4898EA7672F8C9971AFE43E0E01EC8B77D4AF48C +BF1210E98C1DB15C16D149BFF58AB0270CF015B107A3A50F5DC8F37FFB92EEC8CB6778DDB7CE4AAB +C464C4AFF654223006A550EB52485A23D2B4AA7198D3CD54418102F1E9A4FBDE37B841E56F5C2C53 +966DB9B66B000E4588282E3FB80C2C519339F0002D2F83C979EDC5827A3B3C8EF8810A0F9DACB6B9 +998E9AF6551F56313DC4011904CB979AA2D32B11A811BC248141E4B9734D9FB7982A5671002D8279 +CAB93ABE057474628DEFC95D43890DB1ED34CFA8A20BDC3D874E7679A396158E522ED0AB969A4E3E +C7E4474E192590504D54DEB7B260B7935C4E56548A7D121AC1F741F8CDF259EA1B5813175A77A1D2 +D30BA26F65EB765A04C09ED51F69F41551ADF399E6AA2FC09788137BEA4913F17B8EB838C38FB272 +1FDCB55FD65697FF0B850E7D3D1CE266BF90F7EC06A9A0876BDFE767D3A918B092FC78C775F945CF +1F96E859C03DBF630D9A940939654C3549D8F7921CB94EE23D5A0535DE9DF31EA0F937F860B4F220 +A99ADDFC343D7CF7BFA0B803C12C26403F0DCFFC8EA786D0D8A8D9C367419CA8AE41190CE93A8086 +583A1E6C9D70B612C84D87D2EEAA71EC2DC12F4CDE6A821303D5F6A9BBDB7EEDCD289E80FA3B75F4 +7F481B50719DCF4A142069393593B9AF9CCEEAEC56A35B8787193D7C88113E9E1E221D151E093B01 +9EF89F6118BEC4735103CC8003CC5AD1B6727B3226CD44C497DA7052DD681695DBEC3397F9598C91 +77701C73BF0594CE93F23D50EC5BEE2FB9DA1FC966DF148B27B28EE3C89526DD6625E2887F9FA076 +7C127C609EE315626BC14D274FBEA56528DC06A27B2D476D46E9E7916590B156A5DF04A6CB15E362 +45D77021767B6E5BDFCC679670263FD891446C3371B11BB6E1DF60F960AAB4149D7753E6A5C33810 +C42C8BFF4E935003388506F8278BD7CB672F132E065AE684DCA0B9064D01DD620E7FFDFE04F14277 +EFE8E60159BA0FCA3FE2F28B902D4AC275D19F0AC6971EBE827C4A232D87650D2688345BCA78F879 +077114F0463C5F058107B669566F8171E4E284D278405580F04BFFC9902784216E0C9A17AA9B2935 +E66E18A783F723BE044389B7E9D62AA36818FF2EA406C3C1A9D2F3436F3EE7DB8BE86AFA8DAA6A4B +1B84611350D8D27605509612B515E16AA843164D5D0805E36A2B9EF74C5F6A0B9D59A04B55697123 +27F4B1B30E9587CD103337639967CBDC655AA46E80D2CFD24BEB50815B5338E522B3A7AFE8362AB4 +F05D8BC52BBA9C5089ADA8C89529B0275AF422EB540D31A938B8740860756325B966B36817115213 +FAAF92DE63F6BAE1E0064BFBC5588098B61EB83C71F1C2082436D37DAF1ACBE186FEDC4BE7C1233B +6F18BEC5F99002D21CB7864E4811F7AB3C03003E1E4490AD1AC793BD28FCD5EF0E6CC30EF39A08C5 +2F71939B0CEF620DC69E31E39D6DB969049031B0C92EF2DB653D97F370141456A52985076B268652 +FA2648C792780BAD637C4D7581FB2D62011D57E293719487CF2D1F013CFAA532E1C2D39178D51272 +A6AF041440BCA174B5CC902BD7390C7D3695056CB4BD7791F9FB6D88E7A70DEF2C97869F5DBC5BD8 +23C517C7B7C39D624DF627DC9653EA5347BFDA80B723F05F6DBB4C9EA501D862ACE05B9DBDF21B70 +56FBCD8C6D4B85873DCEE6166C8B5ADC0316CA12D9639F361B15A42F00E1D62EDBCA1111972FA0F4 +5758BECB31DB38316F3CDFE1B41748C93ED58B67E9B57ABBED5924A6D53E99FBC9A994A6489A8BDF +13EB685548B4DC6D62DA7426C22227D4D43B6FFC7B5EA91C896730253E8941AFEE588359C2BECF6F +FC415B9EB6D31CCB0F6C7F85853E6449FA6D627A97A3CE8303F148393ADCCCDFA2FE085C6908BE5C +3C05AF00A6F02840206C3253A559AC5C049BDDFD11AD9B118403B84DA10AE3C470CB9A9A2D1D7B73 +2F59F5FE146DEDA60AE750F551AAC934621B4470E1BC324C436303E25F81D0DC3188BE0D6FEC5414 +C20E4CB18952E12CB6423DF7124627ACDE145500D77A97A8BFD9CB50D1FAA008E2CE2B2505A4749F +1EBBB092C347023714055A9B63353AF9E7FEE05BB54C9843698101F79888A91531773830C2C967B5 +88D3ACD2192883D5CE3962D51084FC653EAE2C5FB2DA41DACEFB5C76812D2EDB5B109677289CD199 +8D457FB1023A19AC67295BBC1A9A20A426B06A368DF3C5DD083CB1180D287F5500F2C635EDE157EE +FCEEC5503447382D15C748C1E35F68753992E5C90F900DE54D18F8E1B355D1076ADFB1F3590135FA +D1A36F028E44F48ABB149B80CA9A54614D467F8D71CB310BBC7AC7100261092DB8C5BFD39E0AC6BC +2C9D6CBC3A8C05FF8A74CB21608EC4A4CFE4CBAA2D056DBA14206106044DECF59F957EF8A9CADE4C +9B19D8D30DD4FDE6A9548E50DB51ACA73330142153FC36B69C1C8D5B26D0C689B7040E81AC2C864F +D7C097C99BE5953843E172C97AB5684F35FB03A725A89DBF371F08DDF40A1531FC1B676DB0E1543A +EC6E97D3D2E4AA3D5831D8B3C952ABBFA112352814FB6FAB61A0D680E6640F6AEC8426200CF61286 +F7422CB2F78C61EBAA36D47EC16D7FAF8B4AF31D090CDFA255D9D7C61D46CFB22A7D6E1758E71ED5 +67E00CBD8E8F468DDFB477F091A2F915627F22FF47B876544BC1F03B6BBB98385F009C20BB1AA2A7 +A78674692B8EAC2E3C8069B79E679338DA57F72976810F845BEB6B9ADD32B95D78E5E60F16DD1668 +9C05FD82D36A3115BE8ED494A74DD211D58A2CDF983FCB9CDC29BF7F0E29988FA23560EDF514BC1D +183F3B2A22C09FB179B47E05ADEF48DF02F31C29875D1915037B19407764A4292FE44E741651A8E3 +BEB5F0D972B6327090F664417C84F84FFBF0AFFF8B1D85C822D90730AB4140C42A51AA8B1DBE4398 +4EA8566040EB8B341CCE23FD3F69DD235A080BA5C69AECB9BC732BC2D7D40617DDA6B79FB6EE40C3 +556C7DF9B23DAD89E94054B1345DB8402AE679FC4655A4A776C0150463F8DB2BFC0608EA1F124E22 +1DDAE6026B5E5D007A7E4A0D6B3B0CF3A2669E67C5E4F01551966A7BC48F2F4B6A87E740D8095E63 +F77C7A027F26B52F2299DE5B8A2F6209BCF3D31CB0235F998F781E5CC81E31DC424E008D46EC0920 +2951E5684804A0592EA47D6C788A20487BEA2EC8F2E6C1D7F378B62DB43CA43C4B366F8B4319631C +FE9854F0E10321CFA3B01C873584863BBEFC23C72C05E695B56E8A52E89AA2DAB543834D34DCAC5F +ED08DC51825C5257AE59850D101D84F4CAA1D29FC932F9E0EFFBF7A9A7F3685F61F0490CD3CC8988 +2DB52A757A6AF4C4E67B407BD2316B1C0FFE7DC54E43C87B874F57E4903334E2140B011484863CDC +ACA331175F2CF3D72E0042855983AAF8853D3015E870FF0807014C31D55060DF3FE1FCE157324481 +2744AB51322444632F9AFDA6706E320FFE82B8CBE242A19DF00CE73EE48E25FF49D5871BD3E60652 +298FE3E8D400609E232E0DDC794C0579ACEF89E841B2EDCA50D51151F65E8C1CC3B01EF1870558F0 +BF5743718C3E068617E81BFE120C6CA16E0924BFC2541177D53671CAA3AB641C41557DCDAE1A3461 +47B5E999C4541B08B4AFCBC187AFD653D5B5F8386DF6AD8FE69E21BD0567DF494F736C6A184FA4DE +48DC9F347787CA96E2E00A296C2DA05C2AD9BC423E9CA428D7F1FA12DC9353A302FB8C529AF8688C +BB543B45B2717EBF8F6C497935F4F3BFFD285E0402AB7544B3CA4643AE5A8B5250ED987A95FC1F27 +5B9707ACD0641BD0EE2AE9758494F8D8A51DCE408A38AC20EAF0852D72D84D0C6BE973326793AEB9 +55EAC6FE0A2813A355DCD22F6F2CE56588D1C055CDDFA98878BCEB6A018DB22922D2B600A20F8184 +2E665DF41013CA0947C4237C2BD60A75E2FD1A3FB8C8FA19485730B87461AD466ACB02DF8CA24091 +4FB090B3D2B41EB6B8FF05E1A59D9FD668AF70BA5BB72778953BA55FC5F9F626043450E1D09BC83D +8605098ABEF884639A37809A32565CBEFB3FF39EE53D6C18C58C272BB928E4410E361E59A50F242D +69747A032617C52DEBBF62364AB5A96EFAF642D9D82BA679B1D70FAC10A4EB62FA5CFC308E86368A +AAD7E75948F43598CD1C544A0D4091374D7E88D4522CBE902391641327E888E7748FA889DCE67ADE +61699E7D77763681CAEE9B1CA8837B2F7EF9C18CBCC538C465C8E2DD34616953CCB6030A222C728B +834911C1A179E2C770289407AB28B303E724D97F747D6134B425216A64C6E0B60F633E2B85300047 +E4C90339CE030A0FAE31E830C8ABA5AB3386A3B69267351A7BFDD66356AE5E57FB2994452993E90D +E7C4E260ABAB93C37831856A650D56E44172FECA01D6C7C380F250B82473960D2A2A5FB6B4DA668F +46E624ACF7FA0FD4490F485D640A3ADFC9F8652E7A38CE5799F770C3606DB4B8B947F93967F779E3 +A3C0572F13A5A187D31D7BD12A5C7BE23CB6ED6192086241B76C5BA6983DB9C93E4B208D707D3760 +F03CD6272EF3A4CE89B8E52E6AC5871A3D03EB975759AB4BE239E5EC7842CBB333E692CC607C722E +185D3C39164DD320C6945629C70FF66A5237C0A9520A1FAD6EB9816069351AB0F135D90CC0982B14 +7D2294AE4A38A527EE40BE9CDE2512AAEBB590E134388BB171D0956A7C4566D65A9A041BE6C4F883 +6B3EC3D2ED1B48B566A783292B15B6127920D247D494F070BB20BEFF60640B11B276DDEEE49706E8 +B2B21BB40B7F00AAFC594C492C25DCA774E0B80D82E927448DE2E74A9D0DC7AC9260096EAF187B6C +D6AEAA6D1DC4205B4411122751A5B22688404EA7C5861730371FFAC10F5AFD4727A0E402AB5EA757 +606B75EB86A05E8F774D6E430A1A3FE2A37EBB06700474239FB1CFA05EE44B91B82244C575B52E7F +AF934B04EEB0D933FEB57EBE326D75821C8B23EAA85B583AED4320B7F04B9F2DC591091216FDE52E +064BAAA9C2C9D9714B95A4558C21F3CEBE624B5403B31508F178581AF6863083ED762F1E2E34A45C +FDD71660D626FF8648F5D6C5E580D4765A67FB6159EC8077A9F0A88038C8D3D7C77FF0926E2123BE +874F7BCAF129D55A5B5960F824BD1728ABCFCC51D23936DE9A25C408D786E44C3A2BAFA4423177AD +060D21D38E15E23EB6FFC0B4120E814695D423EEFC2744A1FC81B4DF89D76F0A6803D8B14E75538C +AAD03A72517B86514F6952F6FD619D9E910D980F00964DB325318C045BDF79647F453D4A5CF4E61D +D5359782827229310405FBCF6107C3AD9DDEF9A9A339D5D5A6EB2E7838A0A43221BD62CBDF732DB0 +A638A52016FB35BA7761AEC846A023D3BF2D1BB183543E81EB7CAC1E5970CDC6F068C5EA118C7AAE +528D1396E6DC939112DA4460C890EAD5C01BDC438F5BB734218BA6270ADD0DC1778FD8AB16831D6A +302B814A1A44B07EDC65956C9E6CF4875DF521F3CE5B422F71081B6D69BD270F739095C9E81C0377 +934A8BC6390C420C4E4CDD9CF7E32544C68D884E15ACA3BCC07FC8C132D8FB9D752C15D75C52C288 +57E2EA461A6FCAD90C56843513F74461F18D7164BC597A28AE4BA7C86EE1703535A9B9ED50122627 +71FC12F102E800E0E1AF7BB46681BD2B14B614CEA91B7B2AAA35235DE76C0E113C92688F8EC81277 +D58C3406778E1EC1CC15F1CD9A137C8FFDAAB99ACE3BFC782916F1A877170589A92DC921E6740A22 +B84DC6BACDABCC76E64C79E3A588D80F8F4D376E1B426F15751CF7391102102F0AFAFD8B22DFDEB5 +48AEB5F30B1673023D22054A13391A0EC08DE6E7B685A0D031AABF20B7C62187C0284892D5EAADF1 +21BA28263EB863D5E36EA9C06A77CCFC0E17F593961591F84D82AF823EFE41044C8D606FEF83CCC7 +B0E961E7994DF8A3CC36B209D953E250ADAB8D22D7F2B4E2C9CA39EFA2D93E56195C1560E30A5190 +CC5B17FAEFCF250DF79F6B624A4B917E11C332222FCCFEC4F6A47BD9E75DA9854FC3F7AE554E91ED +DE144D7AEF38A0E3EDB5E5A5626374DB94F022C8CF549093041DE00D7269B7CE544E748439BA2870 +718C08E58FB4A77D93EBC04B7957D272AE1601D41BF85A2BADAA0DF73B0D3841D4839C85677FB2E1 +5F1D6CE592669FF4BBC9C69DBA334DC37706F2F6BE83D5863E8CD6A30C08640AAC4C233684E66B4F +E6B62D4A8BE9D531E47BEF5640D9B5C27D990092BE1597F6995C8A77BE9C18AAE6C1CF130775DDAC +41D34438FC7AD8E042CB56CBF2944932EBA7D053E9376FF398367450E35A1945FE23E05C921096A1 +5454721FFD0F429A3E06DC3ED36F1C170BE79C66996EF8337AFF85B90C5D3A4A94455AE9FA32E211 +7A63E59001F052D5F6223125BFAFA40901E98960ADF7BB886729DCA82FC3B8CC52B37FF2517299E1 +D769057F8154FB95582F02CB0BECC873A9C71796ADBD3E91324FAA94F2C41CF57C30B5897D031C02 +D256C909E080E70BFD1F32E69EF67031138C2DDCD1A8E4B65E485C23C3E450ABDD9815512D6F34A8 +4B9DB715DB2C7A93BFB424316E1AA44397749CB01088428F149A3B4324737ED9957FD388248462AC +1B2610D72BF5C073ECA567E7385CC959E37CAC7E05470160FFA5A9F63B8E9B082937E911586EA165 +374938F492EDF28CE6020953A5B5CCEC7737F9D9CC8538C4339567AAED3794ABA3B9F4EAE65466E8 +E326F6C399B36355935FBDCB9972F10B13494DC25097FCEC5A6398F275C8C151558E74C5175F7BAF +4155E36B733F75CF9D5C5979B0764F14D8306E06BA24BF791141E404C69F3F8FCCD91B9C58C2C671 +AAE7D4F9E5D6414E46ED633A5F78AA5BF04E652246A066EAD9E582B181CC196EA2D3CFAA383B5D0E +4CAC9336E119C08CC6AC55CBFBAE147C623B400453BBF447E96DE036FC025624384359EED7C7D5F7 +858DC0521377CF647A157FC3F188DE5EEF094DBA125510FDE34C570D7BE76AB5DF0A28BF45DDAADB +EA7EEEDB936332DFE93081E0AFD3FDD46BED08D6914B2EFCFDC41662A33B90B03D76D34F48D30FC6 +BBBB600E90E6AC7243FDF026762A44B4D6E4ECBEF48C9D7B696AF29EEE063E557D8FCF0F09E0136F +45D17E608DA36E59F2AECF8493F8D62536119B5F7E1554DFE3F6E8D7C9A2C6F557D18B4AF92C9F6E +050975C3B5C54F9B5F4E39D600B6FA2CD6DE203A174028CBB2A201AF126D1013C229BB82CFD013ED +199D01E51EE2780FE896E01C63C655087A3E61A7F1029FA5E97EA1872F1B45F22282DDC317E17926 +7368CB52DA9444F6055A3C653659CAD2A1D8712BC2B1B32C1DC6906D957FB88524EE066156ED6BDE +B8D832F9338F9912E29A250A8C4674E667C1C278B677AEC9972BE83CBA3FB779893FCB8F81A323AC +91474BA2A2334A07BB5628E905C518E634F6761A3289056F83D5DD7B3890987EEE1C18FB2D379CC1 +905F1AEB3B3D2AD578F0D6C845D2D40C4BCEE3F71C90E68E5417BB8CDDD878D83BA80AD8485F4067 +E5C3CABF28AB56CBB219C0AAB8FFC6C7E192BEC8CBCA1459AE4450AFCC81B9548F40CE2622E5A7C2 +81F74DCC02DAD57EFD92D072318DDF05BF42F1EA8163071E23949B0179CF7DE64677CA99B23CB926 +B3E294194EC13397EA1DC9A5E1CDCD828156CD71F81B64167D4FB01E6002713BD8AC6F82B20CD369 +9C6CA4704DC5C65A2D66EB155B7AF1C9BB46469416FB49C1C7E17A30A5F045271D7DF3FFF2F42C6B +470701C381E3456A500C6BB3D0E47B4D91C5F34B49BB6272F1F8698B307D89EDA3A1565DAD1C0864 +627560CF922DCF5B34C67860352390B282F95394AA2CDE0E97CE3ED39546A6AF1C52BFCF81A29BE8 +2C47C99E8050E4889E4575B75F39E662F2DB7420673797E2ED3D67CDA7AE2C15D0A0A794D57D168E +BE13214E89E0209AB2C0EB7784E9491AEFA3C02D0DF3AE5365A0FC4AE023CAB528162C7A1B173664 +9DFADDACA8DA5FA18B7D6489E4229E9E24D38A620464A744A5C60F6F9D334B908706B738AED18669 +8A8B278341FA4D65A0A88680BA484694921512F7DE93337FC1C02BBE6E64AF2DAD07603279D87329 +1D1F4D39C1DD6D89C90F65240F4808F6F1115CA55B88E242565E59F3BBF1F10EC7B88872E9AE61D4 +4CAE185463EDFAF7DF63DE4D2207D307AFB61501892965170D2945846FCF5973A1D458607F50C15E +06E5BEC715E0C156259AAA6C735593E5564F65F443B78CC7512EC35A56F126DF9D30974A40872E42 +65E1AE5FD483CFCBBBA26DEE426CDC4721F19C3FDA86ED7AD4FA1120F63669BEFE7002B128CEAFD8 +C63E8AC09943B6CBDFB3D2476A026C00A8FF81B1F651B97F310C82ABA5F388CC1DB5AFCFF5996D52 +52A6A42FA4D972E41EE56088F78CB966F9051171C472C774879AECFFF08BFD9CEA40D7C298922ACE +64F28C14E0B81F4DCADE81D71DE3983D87D905192EF13CEE71B2D3FF1A88AEC671EC318917DF98A3 +C9054E372D22A3CEC82FCC217F47319A40900312F6E32B536B9E7A7FA0837EC65CCDB5FB0D414371 +17596CB39D9382262DE6E65379D3A9709B2CFBABF5FC5D5B352425F06F88CD31012A2A4147B112F0 +C1C0ACCC808CD625E0228EEF66661F70AF96D3DCFECD402700E4F6522AC9A856DA466D55C84F65BE +2810A1565163872D62EB81333A698ED7B68352CACCA2D7AD38AB55C19E4F5582F75818302F5FDADF +1DCED09D94872F2D48FB636C8E38C7563C72C771A08C6B1F041F3532BDB39006C89A33C09BE1E3E6 +03622D891F98010BF1DE5355F557A1E09448D486ADEF565705277B31B8BF2B86761E32631E3435B6 +88B79D566F1747BA456DDB43CD239FB47FF7B425EAA4C657C8EEC26EE01AED07CF916E77D53634C1 +37AEEA009C6B515B6342C54BE2C7B95955B1A9DA277A0ABCDA2346E88018C726F481F71D6011AA42 +F8852F2E5749518FE3B3AB668213FE1A05C10A1C53953D75312631D6BBBA01D418199DFEFF8CF548 +6109B099FE8E2F606165FE30F532C03567785D5362AA873C9D3EECEB20F1945D55F49B0CCAC84967 +59FCC7292E46938943C262D78F3212D3F9D0F7B103157F423D71B1ED54B2A603F4C269029918F238 +EC6828FFCEC66009DB9C9E59534EABB183F31D7AD4C57B1BDF0BD2CE5A421882BC10CC1BCE6A970E +2B586BB221567CCA483989DD0B8DEC424C1D1FF042DCB7834423CF244EDA28D2D969B17440CAEAF0 +24A6119DB010CE366821AFA424D1B8299609C04148275AE6E5257A7ACB3C766C747CE99CBA2D703C +F19B7CF301B634D8B613DDC4AFE4633A4D77BFF8E00CFB5E289EBBCAC90A24307E7941EC1685CBAE +400CADD876FCEF7F6557EEE167D2035A05120293527700DC510B038A496BE1D5CBAEF24ED39F7421 +1A93AADF22214ED606A80582485AFE358E3A46D0671148998A3B3BE209467009B43400870359D418 +9A8CEB4D5866AB52D16D9CEB1EAB71C07E6CAA34B70E3096BF7604C22C40D5FBFEEA616DA3BABD59 +DCDB97D883FC8742B8267A16A99B7953225F7144568D566E64542C92E538AC140C851E5D295528EB +7CBB49909B1CAF6409C9BCCEB325468FA0B5F7CB2987382616B477CCFE4F4AC79E4A6F7165363543 +F04DE5B6F6E1C2E910CDC3CDD6C4C92737198F892337DCB6647BD226C820AC99C65D8E7772BBB74F +E65DCAA8A22C33BC168BF48E40A82700A3A7668C5A9A71E397ACDFEE7D556C5C19467B7AA69C260B +727407AC837BDB7D67DEC055C1F45D8BAC61048C45BC9FB3CEFE7549EAA2992D2EDC126FF7A05EAE +58613332A2BC1465B2BC0429162B907D65F793D236EDDD8D35405866D71B25F62DC4A7E06D4DEE82 +840ACCAABC0774F8A63E9C0F7FC980B3583E7A8B01C46590E3BC04EBA565C2EA94F057D964A78A90 +EA9F52ABFD70F84E44E434BD10A42E98C794065724341F907E35D3CB257161E01C7084E3A0166D15 +CED65DA7BA87DBB2EA33D39BD99AFB93D3548358D08330E807F8552CECF63C84F805205491BA3A1A +622E70C232FADF3BF2DCFD6F0539158D3306506F150B0518371912A25EB96163D73E9EEED42EDC84 +D688BC7F7708D9DCA348FAB4DF62E5809BD094842D0A31DBB7C4B41F94D946810C5EC10B69AABC2C +91A59500B2E5D37F4755DDFB7AE4ABF757F4C5BCF77C7F95E6A616646456FE8F18407080BCABBFA5 +7704287AD26222DF91AB2613951E2D679472F8ADF06EA2A20205EC19972299A78BAC52114334470C +5F5890C2F846B4C6042D73945127F2E3910ECA1C4CD7A16EFE4B4BE38A15AAA710682C3836A8CA83 +FD384970139D8B46FB0AEBB002DD224199672FFA02250FBCFA4E649E335428FC71F50F45E498419E +DB0E970F46894A48F65580881C9C4250FCEF65C9B28699408E18B26FE6DB7F1CBDB767564E73CB59 +54C6D639CE33220C894F36E70F71C9F9AA3FE2AE0AA0E3F2E304EC5ABC661675CDE2E70519E4220A +E26FBACBD01D5169EB844750753E6CED53E3678FDCD08AB93E10067E9C64F38B40B76D99B6CD92BD +F4155A1EA5CC824998B59AAD06E09E5F15EBB2288D66EA71B296616734FEF2796F07FF0D8B047074 +A1111D68B99C2B70FC56E74A51B062F4998ACC85B1943C9477E436E5CD7AB18DBC898D21BB93475A +623BDDA71D7B895BA2D4C10F4B90BF335126F4FD57D73AFA50170F6B3C364922E551D40E35DA75FA +891762FA23401D39260F2E92C7807C746F13BB35CEF9DBF2E76E66A72FEFF095DA482A4DE8A42091 +7065736CF4DE904FB52E649A32255E2030A7B31B686353492F31C064A3C4B0448C4BFD44B8E15384 +FD809B8761EE26A7DFA1758D57CE4F0BC376EB2B3833534B15A83436BA553955ACB5A7A66796AC5B +92DB5388BC53EFA27508B08E82821E5CF669BCE52BB860780F749B4F38ACDF5FF12726BF3EC2743F +01014CDE96FE6B4C40A034E9EAFCA2A35CCC776C2669E6AD138070A40F48ED79136D7FF57E993E09 +B81C543FBADD350FF5B5F7A46F060F88E30FE2D8233832D18B6C323EE017EBC1DF5C838321CDC8A8 +4CABCAB20B60A1A3AA028F36EA6E87C850AF8AF7CD50AA6359038BFA8818821D02CEE8F51DAB8C05 +F7AE9797814D97F3DB8CCDDE45B21DBB15CEE292FAA534A5F317B357F4091F3DA357325B8B9F5EDB +45865415973C143E5E5BAA483FBF2D06CDD4246675EC58B84C6AE65CA743117FF00F229243772561 +31A7F2BA26A9115AFD96C18216CFDF41B7220ED0CB3FCC26C36380007B382A02AEAE428887DC8BE5 +FDD630AC57EE3DC156C7B8B29E687F24442E35CE10BA4087295A641F7139C831F7CCDA6CCEB5DAFE +537CC1A97C5A337D3C48A6AE947F58A30DC08CC7B58DBBB4737AD52783C573FC1E9408F55495A80E +7FDA61F0B9C4F090158F1A416249EBBA936C27BEFDEF19D1BFB839EB70576A010706D8B95657B218 +9C2AE04C11EF9E57FE09880273761FB4302C388BD608FA0C7F00F033C9C00F4E3D5CE2D903E0DA52 +E69C7745EE9FA75E2AD93DC6CB5CCFCD3782A699B807AFC36AD1F62B05856D5DFD6F88831B90EB3D +CD523582A49732E3FD7253126D39E8AFB8458B5F7AD7F94A8DAC13365F433C857AF4A42C0A08C4DB +9887C4957259ED22D13CFDF5995DA957EA5A0F620B0214FBFE08AB6D552DBF048D62CEF6EFF12F15 +3511ECA7833E0E3E95F85E6AC0F95438AC4C126E1F1ECF336ED31CCA7EB216D279877123FD9FCD8F +B5E52B587CFFC4428456DDCA816819A8A4A211D8F1629E5D42BA4C5C356E580C8A22C61D987552FA +A97893816DA73D423686E4EBD44375C257F031318865A20F22115E72BF1EB9F93AAA169C140A33A0 +6C35BD4526A38BE79CF40AD1EFA10411E8F3300A8A8B97AB140EE6734E1BEE6C8EE443D698D34159 +97649C6F10F20ACD80236422E215E146D744A262DA3FC88DC0D86FF66512F49D3F957D3C5CFFEB42 +4823509F33F155057A4C6F37B52F4667767BA94F6B8B62856B553F307E5D230C44CBFDC9A97A45B1 +39FFB2F2565EB0E22026972FAD0FB7B9576FB6F368B61979943A398773600E7EE1DFEFBF26D45D40 +BDA66EBB96A56EE9CAE0B2420C5DD83E24DBA9FF885BB844BF3D2BF93B07325DFF60C0CB5FDCCA0A +C8FB5A2E119D5AF26E53AB8E3B428481C2871DDA26EF0B621CD8572B3C664BC7AAC01A1D05B98F79 +1A7080D294BE81099BDA7982432F3DFF4775C44D23F4F1B2E0162B61A8B2CB5EE8564BF98E2ED403 +2219085FE6194C19DAC98A421826CAED7F1AB1477AB327506010217283894235D7DBFC1153D5ECC4 +8AA7293F19592B4D7E95FE55151889BCD1D7FA7DC2370D2DFE11D7E4EA34B5C7A8E73BD3A348FD38 +9EF45B6167FB90BA44C23E912F9A4F2FC0427ED070592F7110183BFDB2C400393BA7569058227926 +351F07FED4F33633BA03A72AA2DC6B598E49B96021DD868DAD0F352E5722FB714F667C15C68D49C0 +3D822D82677EDFE86FE9668E537DA284068C9B0AED83074C92A5B939296D505B837E6A9DDAB1AEAB +7455A08A114C2222B339284674B74BF4CA9EE0C020BF2A148B439C71C6BE51A94CB64FBE4A7EB295 +5A455047CF5CB348B062ED4F6471CBC3E9ADD9BE9B96879AC7BC71BCE02FD02F17C6063985A5E898 +3D205AA1489DA13C408990ABA1C54F2F501AA172F530480D789C848118C0A74EF98D5F607A067BAF +F6030D887AC6A6497F9A0B38F9705F328AAD4BFBB634F739386177B07F22D5771282444E5EE17335 +B4D0EC86117C697E79A5F4F65FDC08E4904DAEDAB20067EAE2448FD4301849E456D085F392DD1316 +7ADF75CCFDB723E2904A9C0C976D6B84DDEF9D92B0E15FB246C3ECC2D0BF314CFB957757B3A3E8E5 +801F520644E4601D291DA0F7507C06F3B9BB36FC1C70EAA444E14E56C0CFF06C7F853DF36DA9D8B6 +AF2544B853DFFF535A7E5C6FC145250CDDA229956019659D0D253A19A7B51A4E538BDC01F74D7704 +9949C2C97C7EC6392C2E61CCC0992B66DAF1AB08551063E53180D2A67DE496716CCBAA45462D9F91 +B66A22545962DDAB120511FF08627131B95E5DEEB8B4DD9643E7B2AF65C0FDCE11F5F1E8DD468DA1 +8D41C8C4F00EA73836F4F70EC50FC3EC6D358C0658A4261C6D15A582A2C7C994E7882E661855B352 +014576858A265FFBC425160669CE159D07EDAC04D060B44E5800A7AAE8E339C29B929AA81D2F515C +46229D2080D5917AB20AB6B34FDCA8E4AF64ED660A3173786FB1A1D005D575C2A5187D3F7CFDC94C +CC44A38C5CD523E9DA726D8EFA6DA7B6131DFF3435FEE838B2C7D6B97934295F06202D307FF78D90 +6699CB9C5BBB10D1D4DEA5FDA5BFB094E704607083B646D37F5DA1FC7AD21B813F44D8C1AFEAB666 +55AAA19703BEA2E77DF3BF350E17C74B3447A452235919452B5175570A006C7680AC05E8950A62E1 +1D7E3ACA35A397D1E19630D094A86807593C97F4C484E4E06BCFF708B6DCA972E3A0009E1CAC0EA4 +141530F5C1B8AEF5E1B933F37FDDBC4BE22B74FE346D1A3F5FEC0818F8E61765568A2AC04713E828 +F98C449D9A1CCE52D10D61DD8BFD084C8D099A75D89DEA64D5A7CC68BD5B0593D97953DADA976383 +F5015915618AEC56D71D1DCD55B89736395C609B315A3F1E1255432FDBD37F38CC43C354FB4B7C44 +F1A7318B0B7E99C3C08C33B953727B6A6328051783A0A33E3CD9E498346A3CA6A77B517096EDD52A +E443B87643A646C3A7BB97F742888D33F9B3127E61942F4103C1DBDCD8EAC8F9E259773066736CA6 +53CE57E8822651261D847C131321BB9D6626A1AC50D047C0BA47B411DF2A995545BD68EC0287CC9B +31D5DDCA8755EBEB10ACCB3903AB0FD5788E984220443B8459E7C078DA4289F1350905881AD6DFDE +C47302B0ACB0D4AF8CAED02B4B70DF3CF8FEC118F0FC2D3DDE3E494CD160E676E300BC464BD4400D +B50EE43B314E0517037BF971ACD7CD327CB2134893B8A0410E68DDC518F5DEC966C7884CF5FDFE74 +723177F20DEDC039D879056CAAB4BF045062D3904F615C5CFE109AC7A35599C94024B41019B9AFD4 +04A80ACAA4837929F5C9317680A13D157A03B59A5588DF79D2E113F5F51021D6F6F90E8BBBA2C252 +FD10651BE80BAFD59C53A3367BA3C28DB6EB9DABF1EA99F47B503F627E15DCF3FD645FC52C5D5D0F +2F07DB4C25C0D1E1C00146E1C4D973E613CCDBD3F9450CC0F5343D79F05E9492E86A1BB889ADF405 +03BD7F3E7543436859184A5B20BD8A172F350D846B7570803990ADAA48D4B9155A2B4C4BFBEF1E1A +065C08E03928559735BDD442FF1E83E1FA20A5DA57D8BDB2FF5427C034CF0128AF111E6E73099E04 +6E0C240E80A73D7BE72B87834E45898D475521CA3306707631F5C6136199F354632D1A085F12A1C7 +C473868B62E534D15F5484323E63D0574196A19EF175214EB35A90873EFCFB92D6CF68761D45E37E +AA61E1A1979A82009507CA193E44B36A806486665CEDBCF387053ACEAB979BD35D30978FC7659ABB +E844F4ECAB3303318ECE80777A5FA5A9DD91B3D06804C4B4E9B4EFCF07EB89866D0DD8CA390CFD15 +98651417114D78776B1A1D36B4BA17746D6BE7FC123D473EF1EFED1C3BC1D555F914536869FD5B0C +35F9C83F65B0E6BF7A627B9202D787D72C600DDB6BCCE613D88492E13CA0AAAB196E8A49928C62CE +A4FFE2D0208EDA334ACF47F20BD793124D2C5546C03F4A364369A76A0425262F9D9118AF54E37D32 +E33AB25DD533A49DF5FBF1BAF4CEAC2D9D378CDCD13B00FDA432D9042F623DA41AFB80699B5538A2 +5403B0B3EABEC9E8EFCF42FEF3EA9F91766902CD206B0787C187D5370B60AD6DCD002DE2DE8DCDC0 +B4719A797C5E26BAA67665016DA0D967FA1346F9588AEDA174CA001B31213617FE19EA218EC23597 +79D979E2663166489C06993230B0D07973A117C4E3F4A4C93CF8428248DD5389414D679C69644142 +67C7FEA17E35B0CEE456667A9B1875C81B2302BDDEA2818D6019FC1622A82051F60584ABC904CD91 +8676305DC03FFBCC64FDDAC8D8AA9CE2EA00D6C97BC63C8A617DEDFC0E40775649438E9F61AFD179 +5E3B20560B01BE5E0983F136CF48AB206954E41DEE0D9DDD953DFD01CAEB569151D6BC0DFEF29D70 +FAE3E198E7EDD8922C0E0BCB8BCCF1C016142C1A8B337AFA7A05A9D7534B184BF3BF827F371E9BD1 +9A71244ECA1BA73D484CD2FAD54DB2F0EEFBD54B536EBCB5094E6BC2F5B2AAE41F05B4B311115876 +ED42C34F8E643B53372E3F6350DB8A38445822EA9A33E27FB0CC42CEDCD1FE2FDF723FC47C996EE3 +56C402112F24D0AF899B2D00BEA1CFD427998BD22B2A09046D6737814448ACFB10D387547D7009FB +384AF0562C85694C071584236D0F1F3D3FCD0CFB38B77C81889061E668BA7AB37AA60F58A3967DE2 +6F939B79CBF10A9DCC42852561D8D6754F1B660D216AAB1E133FBAA321C56E2584BE5C9BAE20CCF0 +0E8DBE6D9C2FCEBEBAD945C3C04101D2387351F132628786F6D9D4CAB83419288D31F9BC600D9664 +12E6AA457CE6CAD26A4C0671097B98C2384C81DD8B9A3222D4F4BBDA7017895C3EDC26662779AEE7 +40D9D7E24185FB821970B0A3A94041A69E4805EC88EE1EE521981536F2844FB8F5EF645F67D42CE5 +148E2DDE43AD5AEF200EDB3A2C7866C98458A92666E5F9E070178BCC39F65A893102A10564AF4E8C +AAA5075D2F8CD7FAB0401C03AF299EA3515CC93066744EB5AF7CF0ED06675BF049A6E3C211A89E16 +DE5BF0445A7CCA6EE8EB0347454950485D884606651E5887FE8B24323E2AA16DE22FC1FC8C4F06A8 +2A1FDE5758976024068197E1F4506E4D3D8A16D40461A4586338B374A592DC60334402F76388AD6A +457DC3F54E6169CF7AE3959676E966A45609621055EC3AF80E182633300A4418E34A66DDFA6B569E +5A13C9115B5FD3EC1CEBE50FBA247F60803AA83976F00117536342DC3D9890C49B2AC701D370E43A +955118967827760F7091469C5406F08F18D7E3548148CF0E312B1DC71DF67A5E7A1656CF2F47F3AF +F3DD50FFC2FCDAB7177285B29C17CA43019F62AC6FBA52D1493ED7C427526470ACC8389BAE827759 +4958908F517B2863B83292EB5AB3F57FFFB08393CA610FB1FE905D88A0A16AC395E2A2A6DD033D6A +0D68992F830B2E1B95FE357BF672716E88FFB92FFC3D62945D1EAD22BC68C51EE0E10A43011DB94C +44685A5C4576F6EF44CBFB45F2A4BF110A01657DB51FD499767E78058199B31DFD60813F1A344F86 +289F9378231D5B151C92385E3650B4FEB1DC91018EAB8474CBF69FDC1496A4D078D2C351C8196451 +247A9DCF8117E5B637371D8E22E248C64D999015C3FD2311E9950B8EE0922FBDD3D7BFF766BFE9E7 +CE0BE12F318FF2A7B5A9C6D00A54401609304ED2C55F5C1EAC3D4B38355BBD85D66D61636FA6E30C +2E82829376BEC979A6FEEE040E452359768ECF90CC539A546F17AE906C76F14F86FF697797322B05 +1EB311A759FE260C1EEE5DACF383816AAF1294CFFA7BF87A4D9BC595EE8F2C2F86FEEE11AD959D86 +F22FDAF4CEC098942A57E57813A0FA99239E994FFF353C1E781D666B8928CFC648FCF0869FC68468 +BDBDA7D280DFAB8B0B3A4CA35B074B686DE8D372C61FB32305169A1A9912F6541DA16CD6316A6EA4 +51524757BE5CF6E820011BE3859FB8B8578C100FF029680E05F0E0BF11D33FE19460C85EA5E4C0EF +28E29407C8AE6BE01CFA0D5022BF9FB01416FFF722A784DFC8FCE330EC95737A854471D334FDC58F +AB42867A7B62836A8B56466E9A6C1247D46EBAFFB905CD4321970F59FB8D6FF65FDDD34BF913AD32 +2E68455C5FF2D23C1A5EAE687F259BC982B6A384D35440F7C693CF50B9ECAC0B5578CAEE87588B56 +2EB6B7F42034C9F2E545EC866316552354EB3728C7D26527ED75174EAF635E048B08DC5D23E88981 +070AD5641A652F2344956E9CF4C16E652A99F4A644D1787D6D36537489DA4D74E61B2FC4DFDF1D1D +9D58F9C26C5EB63200526AFD168AC57D5611ADE4D4A382FC28BB60F9E7D626A6C67AFBCCD1183C5E +3CF2EF210D0BF5CFA7BB10FA3887BDD4CD96EEEAA8F9219AA2F10ABC0A960C3B57C0EC0313AE10CC +FF1F522124CFC8D2D49BFBB0C193EAFFC5B48FB3FF30B21CB76F0A4C0F1377C9223145BB0468A5D7 +1B9BC25873EA12E1C60334571C67385C00D0B570D3FFC6C7FF0DE62C183C76AEEB12DFFEE1459E0F +C818C621B8D12FA1357E2B55D48935D70BF140B4CFFE8813DEFD479350B20DC2EB1D3CBB1A2D3DC6 +EE975D58C89D61FC50E6A0197DA9A586B72255023DE47DABEFB11E8AA02414C2FF6258A281219B9D +DDFE41BA7D7977D0D6F18224FE22F7D4E9355FDB35BF7ED3418F4F68D093AC48F7D8FE4194FEB6C8 +0B9DC1F74E023C604DEA27089F98C3973FF9F4AD7BF7BAE601DB89B08D5D8139B95EDCF6C885FFA8 +B3E4B0477E7040225733826BACFD1EC4A0DD72DC41734856AB9FB700DF83CA2CE812913BD142D84C +5C83C0B2583768198AF9E885F2BA74877A414233207234AA5F18840557CA11682AABDE8993533887 +7C6D404BDE4153C9827EB16D66C1D73A8143C8A2D3604FF72CE579FAA3C5224BAC48EA83BA848429 +9472007DE96466B5B29ACC7C03B05DCAA38A48BFF9F214DE43146AE4E04FA705421917F99BC54533 +F0EBC01849E396216B9F0794E6F6C6B61B52EF1B1950C0FB609895C3C55FF574163FC8B6B09E66AB +AED1810E698FF37CC1F926B2CDA3B48C7D77790EBD2D514B6F385D397F713EC3AD3954EA9C846158 +6031D369E8B99E53408A79D64C34EB5A56DE8A67DE91837960E98A66FC04DFA0EBDE21DB003234BB +78665B039D0A469A0221BD541AF7149A2A659C300132C14581EF766FFFBECBA8B58A5EB3F95446DE +F49AF863A8113D17B2E7E6ECDEAFC3834D4DF900E3475596E86FBB4E2974C090DB4AD61A737D611D +92B4535AC291C56AD8B1C031D2F9B505BB77517B737D70AB3723DB52AE2ACCD5DD2F617423ED3CC3 +9CA882EF41757BF7151806A9B8B0F312808863E3673FB54DE939B35CDECA7FBC4DC3BDF5A5F47D35 +E345916C39366C8B4F439CE1C6F1835C320BD1E67375B03B5DE18C93256F251761A4C8CEC01019C0 +68E34447BCC503B9571FE8000627A6B3DAD5854CBC0A2D69E5A8F46BC78F6A7B1422334EC7A98ABE +FE9B83E01DCF3C6C9273B346F3240EA225AE4A4083CC7B0EA141A0773FDE940768358EB4B13D82AA +304A1386D450C1C0C6A7D5A8FD2BD313F78F85248B5196241E31E5595F3BC01F37700A2DD3D4A0EE +2DD01A36569CD507130E8F5B1E96CB560BB7DA15560CCADF3B2C9804A11D9E8055C9EC70E48C1D21 +3EB756A1376F2EDCB7189D78CD3D6CA5865537EEC31C17D801605EFD860B0B629472690588D02575 +02C6F7A75B9A1C1B397781329832CF3EC43C09F1559CD562C48FA9500295CD3B0A790DD3FCD4684A +7C7AC49AC9BFFF36B39A9FB148BC28D37907433943CBBF0CBDAB46D3EA86DC8F81C859C52D15302B +94A9B51C199B7104DEEC9D769C2634CECF8B700CE9C04152CC59C9326BDACBEC4312DEED92DD087A +1C4840868D9F97CAC046581F762F75E8D24D6445370A3F1E0AE74A6478D9DAC37E7FA5BEBEC0A1E0 +81AF89C1BBF7F51E3E2E22C8C405E8671BA85F1BF0DF79A465DAC7EC07F731E00632E017D190A99D +83E27E5C2E63D7DABBA23B2E88334C63721AC5A4CBC5D45F4C177259F34C2EADE01FA008AF65EBC6 +01D8DD16436D86AA94C99F3CC0A2F87134E73BF22F108B825A8963B49C6C685474AFE4A542C8641D +C0375D7EFE9AC1168D9700459BE52D0DA399023E141969F25C0DAC4668534B6647EC85454BE945E8 +26B26DE6E3C4584B97A38E2B40A0D23481BCA78084FE80E00A71A790BF31DF468A435ECC88E60A57 +860BBCA3D65930186E9917CBD209C230E8F8255A7ABC7D3F043AE4D7AD63D9980BEDF062B7D5C298 +C40225B6D03F29A0339E0FCA02138E526F06B9EF47F5E7A8068A846CFDE2BFDEBD24F5A73A66C079 +18662AEC80B43246284FA4E2EE0D9AAB172B1E59A6CC46B801149D8C0DF6DEC9A55D8E1B0EFD9D30 +2FF618075944CCCB6831D336B11617107B0530D09885E5CA11A5F1FCC8D69D603DA16BEA51116D42 +CAB1AA1E4D7B9B4D79993F2BFE53EAC904FEB70B2D330A89780EAC10D12CC0C35B8399F218AC2976 +E57A26BAD20CE2FA2AE2363D3FD2A8A971747556F2959DA74A8963C20B504711AE1CB0D0C02457FF +2E9BF696B159AF031DD5155F21C0F5549B0471A3C5DC8918B675CEBCB23E29322B959ABC05283A70 +2E878DE8EF25EA760F3C5C7B7B49D398283DE2ED837FD59F7C22D62C58FE4448B1049FDEBFC8787E +67D7DAFE9774979BB3802254DA59BCC0219F98C219F84D995CA768B8B5D9D4A32525DFECE003675E +E4BD5D8DFFC11025AF2B468F9207B5B2B42349B98232BAC0759758C1F4A283405815BD7145C93FA0 +8F3ED2826655053A3C2559073D8ACD199DEA2C5BA5F616A2E48548B4370EC73493BA07E197165DCA +774438B0766867819C1154D1959FE6E01E6312E0AB91FC2E2BD240FC8652A2D456A1DE7F34EF372A +53794D4C4E050BF3CA5B7BD2F1B8DE93B4C8002485CB219AD2D029739FD3C81CC6E78EDF38723576 +1A57143EEDE5CC887F282FECD261F6A25D0A7E154ECDF5DC38E426811BE86AAA458577E5E0C5F0F7 +5AAFA9C41E5D1DC9D91ECD79B514F8CDF7A5F1A189470D35FDF4F9B8788879CCBD91B427822ED658 +389E981E0EE5F7FB87692A3E3E931DF8A1D1573E3B0166204240B7080089A09EF7487C9AEE2D665F +5A82F94C877FB5B0DC531CEBF1E71C6592CEA2401E4B5122E5091DF03D203DF979B9A6EFBA12E2F6 +B422FDF15D49AC0914D372D21E871DE65CBECD105FD4A3E4714B9CCA5C6803FA39DBB015EA8A88BE +7913502E562E5B170B87BFC8572DC9DF49AD63694311EF1334444BDF0B4CA3245271C1F7A4D7FAF1 +703E3AA0E1EA8D5C6E821B28707EE0C9B4F22F23796FE87356C58AE2CADC191F4C58E1FB58DA03B4 +5A25AC95DBAE13A293474217BDB214742B9D9D6AF35F70FED2891942EACE3E625E55FFB820543FBB +250A062D3D395BC0F219ECFE0D76686AC148BC41476A887BC494DDBD396BE200FD3E03CFA12EC9AF +6B934A283C42AA05589AA6B4A8D16946BB51F50419CABECEAEC5AEF9085C9989289E9B46BAFB6FB2 +782D84DE2B068F91A9744AAB237CEB1BA513E57E4C307108E993C972A3E0A898D5A8D27833155031 +FDB98863C3BE7FEF3004CBAA5CB60A1F2E3EB4D7290FF5FAFA088B1CECCB6CF51A58DAAD998F0839 +6CDFD68F5ABC9C1CCB8F6514107773C69C26873E889D1F79D10E866910E4684186FCD71C965ADF62 +39BA3418B313A27AD632300969B6F284519366ED85E7CD968D64823F8C59B5911A72D0A20EB72B60 +3A61E36F52F256FFCDF706B4560B4DFA5D918FBC530D83A4B3C01BDD3CB4572E24242D141BF9E775 +36693A0407D002E09CDA5B195BF1CCF430AE9824C07928A050D0B460F2704BE8F9E647A4884C4567 +0A81EACF7CC038643EB0FF18A376FF6F32B6FE4F197273327FBBDEC6443A299CAD4B26F7778A99F6 +5A11BDE047153E764039EDB251936AA43DEE50DDFDF8856519056AAFC4C5AE6F2051AF0579A9ACD4 +1D00775D7DBE70022CC263DCA5E0A25B9C7C4F5C418587666B2FE24816B1E0EC92F9074F1403BB83 +AFC3F1D52CA79C387BDEF864366E34C90BE52F7AA09935373A07E4E026224E76F9EC3CB9E7EDE50D +EFDA48248D61F3CEC880A3B8843306375D9711E58645F3625BDB8E87052DA67F9794EF4AF8DB0BCF +E00677C3A26907DC651BC838C40EC39E2B5A5DC0DBD345944A6C32226089D63C52490FA10B215AE7 +03CFB663EB8A47793B84CE7364DA1C4E7FCE32DFEF09490121222774915BA59C78C2275F829D15CF +4D8686B095C38C731B83D48738C25F40B8ADD487C350A2EBE846C3916AE384CB1050F9F5DFE09FCB +D9129C6270FD86D55A459618FDFA4F907E6B4746196BB717865AB378414029017551161A52E9D24B +E4F7EED553A927933D4ABC8F25DF607779A717909CB4D810DE8F5762581900E224E4B91598149BA4 +71CF8068ABE8744356B261600BFCC57FB8BE45036CF6571D9B2A95304933BD4F17215F8EF53F8E08 +1AF61FA7F9583C34EB5655CB0ECB82246959F09091F36989EBDD646BEDCA614B9A61AB7696B3FF18 +1058A150FA6EC1BE2EBC7F64357A3FF2A2B0491D2F4E0B970DE5B7788B467CA678039B5EF55C88A3 +84578D427FD2CB16C87B0BF0A3D37CE8ED43E0F049AF2436344D5F47C948C632C94A287509282561 +6C64C5D262FE5B24916FFEE982A69A6CCF888BD01D62EA591EEC51F4B7DDFAFFBEEA93FE08D736C2 +0129E345D06B10246A5F57151C198D407730713F32299638EFBDC01367E23EB59AAD42A83AB41B43 +2DB462652E29813740F4680A5D4BD47B18328FAE6BDF4200CFA4CE3773809B45E8887C9B2E423698 +9F6C48D64F5986F563D9A7538A8716082F81936AEBD0461E6F4BD470436D8B7656F0FDF89108E6DD +02ABDEF907731D458D690BC608EA9CED09EB1E6E64C0790C7A2378201CE997FFE0317679EE1D4EE9 +F91157449323E53B4ADA8096CD628B5861BF794543A98F2FA2AB54FF0F25A13DAD43DAF9394329B9 +5AA53CA32749FECB0B2BC035DD1EBD53FF9FB5AD8BCE06CD89E5568091C1CC314CFB1D9821D7F9AC +7C55F55E0A16E39A87D43148201B928F3C42B110FC056189DEF183745F3B637441DE8BD4C3C7EF12 +F4258E306B2877ADAEC63441010750DB4E6269A4C78A0AC01BB3603C386651FE814031CB5D8C1F14 +9EEAFF652A53E57BBD4C8C0CE36A84A319A53BC1E5FD3F1ED1EE72F4C1A9BF264B594062FCAFB22C +C1FDE3F2E3D3C17DD3F7FE0E15EBD812D550227C06D01127385374A11438ABD50048E17255FCD2BB +85122A6FB9B7DA9D5E9DE8A747FAE0DA45A1FCEFE92B9E70A5B2CAC668D4D07527A5C1403267D823 +048BE671F725CFC7474B44FC5AAA348420B2D7C23C6CA066666FD6F2208E329878D90CEF1C2E77ED +22D3BEBB9D547810B189F08920A27E7107F208591A84D463CE2576C70C3DFE6643E4EA93F4E1DAEB +41D46F0E2F56FC10C69AD5034FC9859D31CF27A3A1EE256C93111F81C11ACF1FC0CE20B90BAC9AA3 +27A5C85A7985B951519FD4B03C40BE637162AF41B2FDA68F0D1E9B7602FE2659D3D75955C579AC51 +DF6A552EB9581AC3F712F083F19B52A6C4F560F36C59CEEB0C996AAF1728A2AA45DCAD79BD7B23AB +388D5B0B64A2B95154B6259B730B0F4A72C8C7F7CC93C7D64D9D8810D1F63FF8ABD4DB89824E2D26 +4FDEE916C41E299211DB1A53256E1DB5CDD04862F034D9404B73183A99D3D13D642A663F129B6D16 +7095BEB4EAEFD03DF2FF2F0B6B594C1EE90FDB203DA89FACEE23F1BA3901FECC75FE1811BD701259 +343011262B6A0A9707AAA6316BC3C17F787BB80AC8DA5AAC942D90F80C5A3BB59E47EC767244AA95 +C63E50BF809998957936D3BF6ABC24B0A397258F9EB4DC8F65692CB023D9091FB180C69498CD0C08 +BBEBADC84A7E0016E8F8BEA325D924EB0DF82E75D2CC2CCBF039B11934363D4332C5FBC5EC556BE8 +5EE4E707CC2753CCC43D2ED50558E51A104221C9323CDCB0199B7B83454DE3FDC810D0F362C0299F +5DD981B31D8E3DDA284FEF9DC8F9C8DE138D3065437A7FE8C30572AD06D62E8527AD37AE39AAB0B2 +25F76A25F6C6505241ED73BA494CF923E919F688DDEBF193E188F8C4C154F21631080763B4D091E8 +AD1D2FD6649E0CD9360E8D1A67A5B5FAFC67547CA31C95A5EA8D4EB5D68B9F6D6532DB9B54584735 +9558542A2AE58C09F3BD2918EFBE1699E9C8F2C2A11EA4D224C726D2ACD4A8D8ABAEDC6588CF2AE5 +66528B94F55B823A2A1F7BE19000F3E7579D094E047075DF18C8C868760295533B26EB3ED90635B1 +29C17ACA679C3E88B06998CE5A7A2544B700229F5A6A504BD3E45B276471959C8A3F81917A534287 +39B5EF9E3D463B3BA7318448E2A3E79520D2D245A2A72F31FF7070B6E4624E3A5E216BD103640C8D +F387E49D732529C611F8B971073F17EBD2F6EB18F9B74A67E1997926DF178D4C9EDED435B9682F1A +279C81BB9F60DAFE125845A2FF3B02979E5481C78A45C479BEFB9FEF3CE2BA9BC46C77B50B03E48D +A6D17B76F06F3AD118371ADC69E178C52B5FB4B261C9311874ED07DD6D5B3226A005FDD7A6D53848 +09E7063F036CDEA41619122635E835D2D74CBB6AA9B38CAA4D819C26E95115FE0DBAB4198FC5838F +2C91B7A87B07D734C6D4F4F83444C1E90AA9BFC908A2BAC4B3DEF9157AFCA5248F2DA31CA87BD363 +AC25E9E77F741D4B2C6E02F04987A6F49D30E9038CEFC41BA172DD675AED8B392164411144E5B738 +F3210B0E66B17A13CB9631C33D44484E792A7C082DD0A5382F34C5637653261B1EB6D2035B08B4D9 +1FA9AB770CAF40A103629511F7B43F2743D7E583433DECFB19C21FD4FD0AFCC22A4119E77C87BFE6 +FE50068B22479015BE5A9F06BEAB4D37412E062A45E0CBCD7BB39FEE747E96306F79FC4F2E8942DF +5D9DA0E55AACCDA547DA19D30B8404FA121298B44C9CCE198C708C69A8D6BF17591C5C50D3FC5BE6 +961F7ABA8F366DAE957A1C3730DA4A5B4F035A9274675EE3BBF0CA8CE9D8349F50CABB1C3EA4948A +BE6F9F143592F1EA95404E6909A909168E3279A957AE1924245C356331A75E7008BEE92BEAA304BA +40B7C3F48F74D9018B3247DF50EBD7CE541DA48ECCB1B0BE51A455C3C13C279D4D8676078C3EBE43 +08748D52C9B041D3E7244C745B1F2F742D010A9E60695F3EC4FDC1050AC082B905D6A57E8F407A3B +472F731011A5798965B7B1A307E252FE02C8F79CEEDDEB6E165F1A94D7FFF18DDBDF79477F14E9E9 +3981ABD200FE7771B29D1D2D120EE79D28B9543818527039AC74085EAFF241B56D08220C958B5D9C +87C0C04A14D52AFD475B542D391BC54FF33DEF8D9484AFF6873BEED32DDA4B371112B523B6CE22B4 +0D1B416B64C9370F1CDF2C548F4CCBE9E12E21C36CC3EA52DA232DCFB65F66B22B5E2EC04852510D +5E264EE939BB67AEC4764B87062AEB7F680B40BCEE04AD45C7519EB3B6199C9E0E332661463647F2 +FB7EDF303EFEF84891CEBCF0FAC5F723A9D0476C3F8C092604C87FC69C7A90F4D64AE45A478EE8BA +2DF50FB93F55A3546123F0B0E2C1C40C98EAAE9F0F26B8F80FFE6E6B94B7E27D2884D58B8A119662 +2DF6BE608C5569D7864BB756DF2EDD184B90812B44ED4A32D001C31383A40AEEE9743651F7950846 +15C48E402DBC01C818D477EAC0347795CB2792E9C11E8FD4A02E194EED1C919D4598FEC003B6D9A8 +A0BC7D456047A1C0579453FC1D7CB2D158D466939A23D7A7B8ABED7E2777EC7487973E73F2266D9C +250CE30729E3C5223AD93B9AE8443B35711E446A3DC660123ED45CE1942A1A2AD0610467E081CE2C +8B92A6C82F0B17B5D2429E99F1A6268072C6B5AAAA6EB6283A872C54D3694CD825EB2926E57DBBC7 +C1663075E687A144E4D61C225781D80FCAE1497B442342B4A3F1CD6BDB50E31791CC3928C30835FE +F845B6BE5E2D7E3F2F5F085AA3FAEB45CAD0D76BCBB1ED859A9CEBB9F7457036F0BC3F195CB1A98C +9C8648F6583CDBB23894BC719D68C2DBD8003B10D08C8CAA40BCE784D7BFB4EEC9EA5359AC056E57 +B8B0F2EBCB1F4CE40C87FC7861180133E0CB6CE2FC4FE690756D327A2B5AE063E3021C0C0BD420D0 +56F0B941E6B36088A55BA11D0C35FD0132D5F48E5D9673572347171B4328D4807B972831C0D74CFF +A5638C145B89C989E6EC942148207D6DB82257585958034D9F9D4221C7C9F7013790DBD130F277E0 +BC88BB179DD09E27062379ED06F25EEA8B7FB33C35861A0034776E3813D2E9E5C10E227CC569AB36 +CB2D9DF2E7B7B44758F9DC4FFAD7A24AC7E9F47AA850C221048C3CB35A37CE8EA75632AE65FE3212 +175146FECD6334AE3D3C5F492F067F795E1E8FF386BA198CB74F0BB4DC0000DA383BC4CC3F070DE1 +7721431988D69C8B1A5AFDCCC83C22E16A87E01C6D3E79DC7AFA3DB0371B0866EFB8B6F88900472A +FEF1C4A878243C52D4E02E82658979731C841C489A6B97E271C4C93800EC7D91F93EB9B9C659A554 +E1FCE42A5EC65AC39190EF4B66DEAF6FC0569A000A9E1495F42F706FBEA4D32EB7EF11A648910259 +6A65CF899C2F322F5679C6D123469192A9BF1A7F1F2C81C554ADB97BD19ADB746A4F81A4D5559E60 +AB94C483DBABF6CE2F28CDB412D50FF3FCFA3B3DAAACC6A83CFED910CCB3B8D2C19590AFF4D75303 +4A6CE7F4156896A13808E0DFEAC547E69D3C886691728E4A35ACD575B40D721E8FCC5385A2EB28D7 +08101DC50811529528F5CB0C009BA7E3C88468E37768FB0D83895AB54DB2DD5426562AF9D8AF304B +F6EDA54E9C92643DF926F5C3578269750120302A37CB140A18BA56BA01108D4ACACE8FEAE640A6C6 +958EF156B588ADB0EA5F3B0F37BBA12B7BCB221C811415387B024B7076FA4403A3AD6EBB5D9C26EF +EBDB7ADE7C60B444AB9F90EA493B658B7767AE2BE649BDBB3FE85F460F1ED137C61BD95F7CD3D8B0 +15CE45138538930AB62AA0E54B4CE1A5EC5FEC0A2B28B345B67089A4E4AE14D2E1F5A9C8848DA688 +CA298F93860649EC3AAFEF3E820D86988C8E3E5A4D4BB937791827994AA3E81D0BB3EE115EC36D5F +B9A392D09E79AF514D11C7B3A03C9F9C13355CE79E119A19177FFDCA34704D38118A8976D1EE5AA0 +2D14FEB1414419F5E85244ADC5C0A765A522EEF36170064BB19FEE3B5F7B441E4DB967DAE0BAC2C4 +8FC6A836E0EF5A69F073BEE1699F55E9C757EBD6FD8B514E2B49D6333815B7DBD1E0694695FCA3D2 +1320A0C4B852D9706DADD8369A95FDD917328BE93DD33818954DBD2C212D2CA81560ED5BC284EB04 +7A5F389E24E43F4FA8C97FECF46589FA7341076555CF55B1C21B28E0C1CBB00AB8B6F67472F27BC0 +D11148F407824B0159B5188D4BB7386FBDBF1C0FAF34721B7BCB5C0FCB7C4010DCB6A1284E9D7883 +9E3C2111A05D29AB7997073B590A81C6168020F1D48951BC7D8476D5BA593F4F23CAC1F9BB0E091E +84B4E99E5C584D1370DD12DEE8DF16AF8BC6B7B23E2FEABDB7F32779AF8E2B5094A6E9B7A7225F24 +C43A8E5D2B977E1E19E633C26771E23017ED233DBB02C64F8CF03992C6484528D0C8464B46F24F9E +8380F385D5D01B8893C67FC103498983CF939432AA380CA576D09030CD52FD99BDC3BE16C7204CDC +3365BF76294A83A1FC14A236F5FE5321904E779B13232A76F8FE521F425562678436359C2461BEA5 +AB27209541F557AE2AA60009C9CA0A9FC7898C14306CE35A50017BADEFDECBBF94EE2905220706DC +806409EF87DB1D73EAB0698AD2DB72CDCDB293E7FB13C94D9FC87E74502E6927A212F0D7D2F2D194 +64F7A66AC07872E18CB1DDE8F11835DCBC5C4EF039333FFFC0FC1456DAADE7DAE3EC2EE0D3415B0C +ABB69FC5006F4D14A4EE1A5CA99AD4D5E629C0DD1E0F097B5B93DE2DD001A8C418234C9C45E8C13D +1AE04E9466DAB8CF1ECB88A4E059C111A6468D2DABB90DA79C7C79E94DB28F6968B1A632F8C57D9E +565FF91C6916026FFAC0661856B9FB8DE9C81661816221B1FC159CFEF1751E7E403F5F2CE32529DD +540792FC17A12A3DCD7C50D38EEAADBD10ADBF5D8A82442AA900CE6150EB7A4639DD9FB6E385B2FD +093493DCCD9014B23EB172E21AA89643A6CAD1093343D85D81261972DE0ACB16A4C6B5F0BE4C978B +FA12D3CAF0134F9EA49F6E9687C8F99A456745EA252F0BA9968C7F9586E3DD841AA92DC7705BDD68 +2DAE41518A09DF0E209F321D7FA3417202F4BA76A984DA3ADDBC58136885362F02F0A24EBC439B3D +BBDACFFD8498EBD29F88F016B1FEABC10785438EAC860B554525F3266097A675299AA0967BD3B7A0 +EEEE3FC578D1BE99D3533BD91571AED904BFC9DA1A1451FDC5406E1CD614E0C7FBC733563CD6CE6C +C31E9237CA153F1F0411114361D731636BCF98555ABF12848AD109371A42B63675A4130B81E97C2A +2EE2BB5D8FAE2640156001AF0F55D9D5DF8FF23C8AEFE14F120000F14149A36E5C94CD9081DEC277 +C2C34870D05011F99D48B0875A5FF542F067F7E9880109F586BCF2B50522A1F23ECE44349E539E70 +F84E207DC9BEC7CDF856A046F1A03226AA41F541719AD1AF88FF211E57DD0C1275DD0B7B47440DA0 +89B98C6EE92A7D94700B83CEBE19EAEDD8A615F6587587BA8BBA3CE3AA5E8EAFB1FB0F486BE3609B +169EFB178A4292F4C0378AFE5D24EED1CAAB514DDC66C696D8E37F294A6579131DDF5488E9436609 +ACD750C3DB0A940C84FE022B22ADC2676F62E91E8F891225F891FBA537679B24547BBBF35F04915D +20B11739F620D18B5B216921D222F15044368569AA302980B9225BB839F494588481B94B0C724352 +B2DF600A22B062561D86CB8F81514FBDAA4F8A043A0265F992FAB71FC9124A45B8475E1EF3DF6B6D +E35CF329777D45F08325E8505EC0D979F542807AE77E57E453525F23BC59A50740371EFA98678AEE +6C425374AEB745B99DDB5D8D908FDB551FBC0DB15832107BBECC4E11A1A8DEC69358A574A2ED46CC +31D564549EFF23102D92BFDCBB2BB985F78F36033E34F59C0EBAFA3BDD71338736464CEFDBA91398 +33995EDA4207BFD4A9867D32E867FBEB7DE60D132803EF9347CB17BD91315484EF6570892297DD8B +7D966103339535E28A00CB1EECA4A9775F60A9F5FC9BD8B06D78FE8E6318C31DA2E847E3F9CA587C +B01AE2BA0A2EBDE308314413F4F230A758184ED60D4F71F6CEC22A93A01B6C54E0449A3860FCA895 +4A347B7588329A80974ECBECDA1070FBC055666375229F13DD995E99265DF870BC8B8CC6347FADBC +1A6AF64599271A475B9123493D46BEC41289BEEB67EB97A8DED7A9C9730D37C65164CFBDC22E5CA5 +89D2E7954C7136EF4E084C43A6C7F361A3E96989239BDDB9A593CC2A80BA16DE9EE90E95CD39393C +212AB22EECB677FD36D34DEB46C4AD0D21BF7E6D7CBD0C8083842FCD87B18FEA7CECF939987E99BA +34C214E44DD84C176C9CC5A4CEA76D380CB316BB4EF9DE73D73B4AFD4ADB54451591DEF86621D138 +D5A0A29441502BF6C2ADE671CEC3CB5CAB903A657EB2D70C943F976C110E46C5D9D29BC00A875F27 +38E5D22496A43E096E009C5D3CB724B4CABB32838DBE527F83B18CB457E57B092C302EE557FD4F00 +DB9C56E66C9FDF4EC9FFAAB85F60D02BA79694FABA476A199A0331C30A78A92E10417BA236E23364 +8174C826331DC1BAB87C5F95027846130C6A2B4027930EBF9A97BA1B039D386FC51C302648E25980 +212F6A582CDE2778C677A01FBFB3C5D1B8A374ADAF6ADBF7DC94075F25ED66D440B3922C5F255FB2 +3FD8F6E21EA65B1D93BB225684B50F11310E242B087575973345B229BA62C1E2C35BDAEC04D10148 +F5B2F3BCF7399BDFDF1F3F79119714AEA697245BC647316EA157484ECB951BE367234FD02E8B1F09 +1AAC3D29BF282DFF4011BC0CBA8E55234D943DB3017CC7A766720BBC29B2D097A956C0F1067177F0 +12D42ADCB473CDE8D1BA35B4030757FA1D8211989DF3BD22CE5D501C21EF8708FB3449DF47D88650 +9FF7B59B76C0DBAE443F336FEE2D615D7EED1C284F14335BC8A26BF4621E10DE9611FB2F1DBD52E4 +B7565D8C65B54EA36D508BCF0C578A49A2665227CDE1F9768EFE847F9D94F1BBB7DB83701C232198 +5C7283D47B2E40B27A268428AAEFE75F6B2F8764A8494E5827573758CB9CA46FA93208836BCCC8B5 +564A69F5AD882052AF1C1417C3FA7F580569528682C77080F3688B65E7FC24D2A3AEB61574B4A321 +5927281544DDD7A6EE0A3E9388F8F631CE7251724DF70726E5912DDCCC8C652DD6C9608F8462303D +867F589DE0F2F71711B35142EE6EF93B64D6326C4DD7DC83278E057100EE772082E6BA368ED91A55 +53ECFE2293A481E42F83BC8F9148C70EACE91F7B7D9CB8A72415BDB3AF66F68EA733A17ABE9DB005 +3BF148629132969589F38D30EABFA96A01FAC72650B5A6FF3935670198A1EA33810A9B11E330EB8B +451F24F93544263436F669AB5A90A53B16CCEEAC36B1445574EFA7E802DE73522BE725E68704822C +B7D3912717333367895BBFBE06966A5CC653AAB5E9B3596702086BF0010085B900711932A95ACF15 +CA4DC45A754EA334E9EB84D6FC8E3FC4F897456BED64BB93B593549FF0D5352275D8E417172A6664 +C5E0ECED1019494A7ED49AB0B965BEC1A82E5873766BB38D7D856049CCE2FCA65AAF61E961B60634 +E2A69EF059754C9D8163D87F928C222772D070D83FEC6FA5AC734AF65E40BFDE521F7D9CB1650FDF +64754BFF21EA3FF0AF7611A93D525EC9B28C51AFECB04E7FC8323DD6C9B0D8539A34FC3CD8CEB795 +8E8EBBFED4313C77ED469C199552A9FF70BA5423B03B6148D4EAAE17B71C5B39DC436AC53D6BA8A7 +AD81AA8B02335A8B2B11E9F4FA913159A725B8AB60F52F1A2EA50EAF4D56656E615BF382CC68A690 +BF83DFF24FE986570ADC0290ED1A37C1C2AD469CE789E0EA0BB5CE01020100E729721AF3B5BADD33 +A2DAA6C33EB8F9064F5292F715F820B4BBFDD56F76D42E7A1A068C1CBDCE4640082F6E7D582D1939 +990CE6EE8D270015A2C461798B37DCB5798EE9F7512168B76D26C28BE4A49A1BF96C89D235F21A1D +B6A96E5DA474D0B19B808D13D7A11BF39EA8647499C410ED9894A1ADF33D41B6FC2E614D8087F4C8 +4E437B136F3CB32DB8393C49177A0675A0C9E7EECEF448A97AFDBE840FA01FC7E5F2E8FECEDC1884 +84C312E8635CD79195475DDBFDD4D38D5A0246DE2C7F21608F8D2C0DA1371D302E941572E5792A3C +F4E51A33228B93A814D03FD4FC223C314CF3714BB3A34BD4F7ED6348577FEED9DEB082C4049E57B5 +D3CDB7F26629E9F3BA36893E09E3C7463D02A22D7056BE76B87763260E46E48BB832B7EE13F8DC05 +37EC8E81E9BDFEAD8C27EBDF1AD706933EFD11131E12814F236EBB01BE85B7F1B2D627413B324918 +D247604F56EC128909873FEC3857028BEF76A3494364C2A7002D104D486236C30B48E2B75D851C34 +EA50BA7FFEB4E19190898AE21768C157C0CAC628A2181A32796FBC1A7271D2473CD88E5395DDBDB1 +FC3AA8DF0F3D588637F19A8B833AFDEB5F655A8838EECD684E2315B72C75CEEFBCEF94344ACE8D6A +DBE355008EC72FE7CEEAB01363A895F4E73F867639BE0A0BE67333848816B05B419221BE8F9066C3 +62C23FE85B7F392930BFE4C12B9526FF2FDEC38F23A159ED61A0718E7115C24597D849FA76369153 +54A40C965D4D72EC94DA61A03766AB39AAB684E134FD1407A5B1B19BFEBA52AA0DA5D99CBE5C82DB +AA663711E6DEBA180E1D4A39C320516A4350D296BC19BF1BE054859A0889C7E9727A021F3176FE62 +0FB0C837E4141FECE531A950C03D319E3255703220B7185BD20FE5DBA673F8129AB211EFCF36EE39 +4C7E00EB0876624BC840FA86E58B2F584754CB6BFDFD76810E300741EBE4544E5AC17413ADEB21C6 +2F66CA4F075C32381796BA709782DE34A675B717A2C7F6D88104CB924FDE5DF775B4F0B68E0E2E5C +2F788BBDEAF06D8E1FC2105CCBBD5827C0B03FD6CD64F0D073F3192D5F94839644E5EC6C5185BADC +F04112A65F49A8C83174A9AE958E76A2F5AF469E8B76C833782C5FFB8BD7B1BBBB3EA0CB7C9786C3 +BE2ADE5E7AFA8C8F20892659A59BC421E28845A108E34EE17864042EF587A6D67DECDFB3F510EB40 +D2229585347A0035670FCC76C2837A4E4D68304FE113C539B35C1F0234B5079B8E32934546982978 +C5E4DF955A454EA263C3CA5D7101F31A318D82A3F9FCB5A8AFD7A65209663B0FC9DA400B26F285EF +46D0E1EAF8ACB1F1CB805E3986D04BC585073FC64895E4DAE1CCB749BB439CB32EA91176D5C39C36 +50D10AFB9C9884D5FB90183424CEE67EF2175D01D2478D67511EC9F54F88763C152697B06D948BED +49240096EEE3D06AB4575E8E8B2CB8263B5BCF4FA1608720F52B675309833071879DF52C3EC2871D +20F398B5CAC8F8A4D41D0F1D47584DD90DCDAEA4A1CF160C4B3BF1AAB890B5CEB6CB3488672AA68F +BD938281DBC1D8BCFE92FBF514DA5358443CB6E0147254E91B38CE6787B2BB0DEDD2D38F5938737A +977B5EA42892520C58F8FBB53C994B57382379E9490F0D6970B980E1BDF8CF9F4C3C5E0A18F66E86 +EE93FFE7FE546DE50F41364BCB3721B637072571FA1779F1D672FAD260C16D7F13CBDF3E4376E7FF +56D2A710AC5AC35FCBDBCE2C9C17E523BBE6218617B13C1FA6679B308979AE7C61DA6E68369324C6 +CBC7DDEC364E5A86707266C0B459EE7B2C03FE584E529BFFDCE98C90A2F3D9305AA74D3ED8430DBF +3A49FE2ECFD9C4BC9FEFD22618FE9C8A973AD072AB6F713E4DF02DCDA7AC5359B2D652013E131B76 +B3ED6C75FD53BA58D862846264627F6B9E70D8800F6D9B32242B747A67BB2B45675840D34F852AA8 +062FA6B01E31ED24DAE02F6CF788A17F7B9368175195DB0072259CCE0FFB2C1035C1D26E1777CCA3 +D56A827C3242069E76D6DD69B653768614B9ACFF16567FEA61508D51454BC02F6C60F755AEF6AFAE +3536BBFA1823F8E1A53C41124DE983E51CEC92AEF4F99785D554488A51C20885346D1F761DA79017 +940A0C557D93F1DB6B3D00FFD61D08E96FF3AFCE5FEDF545CC9F47A2B1BB26713431D6D1E47FD6BD +6E3C668B0368241F0EBB5FA9C991DF79890E52E83A3675EE699B61BAF869DE91F67278F510061C6F +E41DE2D883F48CD0E068E2A652B244128D82E5CD52F35F210DDAE3054691ED55A7D99088AAE8FB04 +F525C2084AC09F5EDF80A4EFAFE981F74C0DE9D194320709B3464F3FF2C0F6AAEA6D973D9C323F53 +DE3D741F698FBF01036716BBD62957CB32CD81D3A2674560FFBC5BDC5C6E4F547E589AD0B1CFE14F +5E17FED1C4A8ABE4E67CCF8A49F32C4C6044F1431E1CC382E7758722A6D0DF9ED23E51F8AD14D11D +7B6428E27443715EBA4E9C05D6F238378F9498AEF0E7EE4FE6856622CC8E6ED141EE5F109E343CB6 +695C4BE1E0F66601C27975983BF557C04ACFC19227A1AD7E6C44C00529FC7EDD7F886D24B7E029B9 +C395260088BBFB96972199A7B32796D27257DE83A7402291C14FECDF7998C5C96B1EDADE0280F856 +8A8F5007852EED303969180B3329917973C2D32C080C9765B6BAB0673BC7ECFDBBFBEA980C263843 +39B7F1052591D91667D4FEE413AFC23DE2D4B9DA742F4269C6C939F5FC32A38040730A018155AD73 +3F231E4D5B9D01C03A58EAE7B5F590CCFAF25EDC8552CFC8D95C60EBAE1837D7A97CA137E9D4A4BD +2CD34AEFD68D64B3F4F62326AC429921D7FB3C235184FE0899690A0B775F1A566EC29D5830D32372 +6526F7E7F5AFDD71B77E07613DDC4FC63EDF49051AEB59E6337AC0A4B6DD872E776C9CD0CCB86130 +5322D816732124F5978A86C186BF0A0F88E733CE38E4D7C1BA5378C5629B1EFC97806059990ED42C +5CD183BAD7E94070E4058569DA2E51831FFE0D080301AEAB4350BA290318AEC582C78D05DD92E5AF +B4424EA808629BC972E68F4FF2489C245593F07555CA6A2B25964794CF31CBD3AE5C229AB9B8C298 +06C01D116EBD0FF0F159ED2D3D7DFC73EAB4910BFF5B0B0B587CD9EA6E6FC45D63C09766224D8346 +1F0588140B258B1729F70BAE7962189B1554483392988CF230AF4077193E53330519394DD99BA135 +6D4730AB221DC6A66019BFAE564893DDAD7B177DADD16ADD21D396CFA6C3DC818052E2F71149FD59 +4A16DE0C2FFDD366C99B486C55A6E991E4D22CCB15843F0C3363676AF2F5B2D1B7EF66CCF2F12DC5 +0D63776BFFB058D70A9C76DCE96C754872D72C82A0C33F90D49C935402CDD26B6D743B1F43BED5D8 +B539424849C1495DAE73044E885A7D0F307F1816DF6244A6F2D97BFD4E200E93F69B08AF39EA21E6 +E347A47CEEBF803F73B978ADBFCF056789BB8E6E2563DE87DD9A8C877157B934102DCEDAC54D487A +1BB2694F0034093C48F10A17D32E2BDD0C723CAF59ADDD1BE373AF8C9BEB4415AA5AF36310C31F24 +354A53C0B962573148BEF91D994FE3F3D8450DD4D686725799F53C373A0A3E3C060C2E1A3E800504 +9F26D716E1F381B9F83125E4683264A07E2D8938F605978E2513DD2050B3D8A1012797CBA8961632 +BED260916338A812AE751C7B657E086A0C7DDCD3BFDDFF3E48B84751925736D1310C4910FC114387 +F3ED7FE163F91895EBF55FCB425CEF5729D99BD8F2C072E36C310523E75CD8E5DE49C031C4263410 +9D56E91A46C8C8E89FD92012A00C33D0DEC52597B5C6933291A7BDC5CEDA95DCDA5600F9AE1C8250 +54E7EE1067458CCB66610704C58E4A4FC0CB5FC933D0322A716B2CD430A3AD48DAB3D4CBE9D23F2D +092368CFC4E1F5495C133A92942EC62118D45C17723646E69407B4A89DCDFD2AB3FFC099A21D9D29 +741D68270629AA3A414FE58658DC9170C247B6E23F35C4BC5FF83009F462F2EEF4DBAC5FD158A658 +57F9B6DC1F5192DFB169DCB65621CAB2F1B07BD22F4155A8E9E2B6388D430FDE5EC1C834D22EA035 +C52E1E34482EADC36B4CAE902AAE89A7284E62B3C84B608D6BD05F75BC31310B2DD3B2C08A00E073 +7F104F03A41989D5F6B9A2C38B22F1D1803EE5D7A4D8DE44E4ABD496A1DE0C0E12C4BC96D0122846 +3F0EA9CE9509FEE987139F3DD3F9D0DF4313F555BE85433718F6D05F197C41A9D9C7A8B0D2740196 +82D49F58DD5F66B12A6520D9F226D1DF1F1B65CDFA261F980CA25A92645B86B64606293F8BFDE364 +C47D2AF2C709BBE77A70A5712F2CC26F3D66F5BE2C307A48E6F887F681D30121E32BBD87271B5DC4 +615D28C309F15AD263FB37424E56DDA6E17B998B45BE6C7FC6C28E3394A8764C9EB2DF5C06626593 +B5C665D550D4600172791CD208AE9F37BC082B0B242B0A504B751B18F4D7495172B697EE217834A8 +A4FB7CC16D6F9E8BB400BE8AEB0850960283DCE725249FCC4DE97D9886745AB6066C3E2F64DD8AB7 +9AA11667F11188D7965DC11EB760B772E282DBF13249F31986AC6898FEBFE23E3E8B8D2C33E00EA6 +FC493850ECB2E6D831D1EFCA3C2EC8EE2E394599091ED58BEDE97D7A43B6F739EB0F845EAC1DF6B1 +EBFE876009CC5D804B15ED4B56761B3CE1AF59C07B49DC798A44532297AD73D5101ED47F36A3678F +818297CC27F6AAA2AACCC9AA9B6F5459911D8C56CF499E390AE607F3790450B2B9C9BE0F006EDA0C +715B5CA0481734CFB0597478E7602B0D2C1E4F78F03C68C17C70E4B42D7D2D3C95CF40F73488B371 +8E2CB05A549944D86944D78724E266C3319AF89AE430E777E95F0D792B1C654306E421F3D63A26B2 +1E74B6E8B21B2E2B9DC596D013CDA16D08E65E8F24A84B12B2BADC653E6E1110DE2E709C1C1BED13 +707B70A421B384F20CA7A9A9D20324DD383F28B2D3C7A9C53F5D4C6B7C378D26DF11CF55238BE1B2 +4FA70DCC178DAD3D35670FE4919085EB1CD905971D76A368FDFCF9D2F0A23739851A3A6D2E02D65D +54DEE69ED5D81315D3EA5E356F94EF256DD267FD1E1A9EDC9CD63E743F299BCC4A4506233B8DD765 +2CA067F741603F93250C087D368F9E9CC4CC1A6DED567487C05BAA992B0056A77F630A72008E3946 +15A9DB24FE56A956650EC9DE90A6C2259189440247970541CA198748928215C0E132A81AA13208D8 +63C1FE817F70CA573B54577D10B73100AF8EA088208A44FB92ACA314AE5879706180788C17BB1D0B +81B6B95A1C4E0F9EA66F9B39BFE12444A6446691A7BDB03E0F03D9F07A10A7598F2166F108529F34 +CD90E601FFED3479ABCFCBDE8F051C348E48C61D95B00C59EA1287423F05666C3D36288844067E83 +E14F6B5210842C742B89F13ACD126B9FC50ABE2CA7D7ED513D43B6AC7F41EEDA416BFFFCC5C844AB +2D23D4DC09B2D510504CE98D02E72020D9E669DDAA344C63A1B75632F912A1C0DA3885DA4AF7E243 +E4A4C6493D6595BB6D56B0359106957259E59E336BAAF35BD1CEC5CDE735272EBCCAE8D4904AEBD2 +B32610C6FEA2B69941D6542ECB44D71092A3CF067708A3D087AE99FF29671AB7DD8758759B971A08 +AE1BAD78270D2FBEE37AA2DCB119D72F6C7B0C8509018A70D0B0BE2C6830EF8E0B24B1CE1141EF87 +3A4D7DCC501F808BFD94E4DC0F2915AA023076BCC8006490A43685EA25AAFC187302EBDE7FE1965A +04A5A398985D29F08E085127B56B057334D88EB638A4DDE64AFD204974C3939536B1B66A54B4DB81 +151853915718F70813F096CC1B0EA25E363B49264C2AD17158A4489F91453FBEDBDE15D7B74D7F98 +E81DF23251785D58295BA297F295AA6248A912CDD4F1111E6B628EECBB5139709E76EA4AB743CEC8 +26621D08E6BC64691CC90B3C3C1778931A28D3D5B1E20E96C643316613FC487C9B604C43463FA453 +3BCA1236286E6F5A6EEB2F1D9C34BDDE4595495A365F88055D9268541CF1654ACF478D384A5496A8 +772EA1402751A093582A6625A0A44816B5FDBE166835D598644296249B92CC90AA3FD6445C9A19BF +27F59CB0616C7306070F33C7DF4E1DE64AC8C5BB2FFAC1EF2B1B30E5A0275E6004CF64BBE2C6710E +DCFC3AA4ADD60106334708862FFA6652825BC84842736E47AE6917180365C75B27505EED3C6108E9 +898A780E20C3F606A860229AC46D0471ACA0187D6D539A1B8820F620F72B41AD1D3BF3834BF48CA2 +AFEA8BF535AF74C4562DEADCB63D2F5C7585722B77C989342D190FF926C8A5263B4F25286F99CF6F +C62EE6E2AD61C82B29D82468AC10FD27764278E5558CE8B41BA111CB2F040914451A480C93084237 +CAC8F66BB7C6689F340B8ABF0150E06D5B1177278A4C08742FE22F42C28680F190900344ADFA486D +59718C25D37275BCE4DF981AAC35D2C7E85C72A0188B8953CFA516FD545AEE0BF4B8BA301CFDE214 +4241FBDF3D204E3D2823301572E23F204C97305A82401660E12926EE7BA6EA1A81FF5C007933AFC7 +3266FAC4C134ED818A48E7DA01C71A46335C845F9DA5E960B25339D551582B375814148D94CFB781 +FC56093827B78578A73D4FF67B6B87F40CFA5E3F4325D9108CDB64BD06427B88C84105187316FA29 +90B4E3E8EDB6C78ABF164F4A9717D523794B2FE772A04DABBE688CCA977090979B5F47CEB90A1DBC +167D305EAB231C9F4260C4AD10889CB785169902FC0BED78DA15B8417453BB65856EA0BEA5245BA0 +573F623D215F6C0CF801851C305B355D26B52B0B343645FE25C78A3526841EDA480919A1BBE5F56F +C10ABEAA3E1FCCA7C43EE560F067F1AA2AFD642F769D1ACE8E2AAAF38850F0D757CD808C921D716E +96FBC07DA7860DFA70CEAE2888C0ED3CBF9586443532B68DAED9A926655C157A416C383A53D8F283 +2A4E67468112A09ADC837ED8EC95F70852921F50D4417239FC42EE3624CA97F682745CC5E76CC7C6 +7BD99F2180F8C0B7FB49539C8CC474C25C0DDE491671FF329E51BCFA779346D4686835A3AD6633FC +B5E0F67E0CA9CED8F215BEF4D240453EB2EDD6ADB22278AA5B985FA140C9834D38753DF2014F8C0E +E6DAD19E8FC54C03C1F6CB0F858986691D99592562CAD95FA0A5B2ABE4A8B54B457D42E8C33A2D19 +51C0419A72FB94FDA78ECD92BD2A1416459E9DECA9469F35E4C47DB531726DEE8F203D7042EDB32F +025DF3D582547BB1D45F7A5B70D317DF4EBB16E36B0D798E0932FD2A85B04FD67143E4B287A50416 +2C1F5A037CCD780088C5476385AF8168E12D97D44B0630621759173C8F1E3006B5B1C6D7138B7EEF +C3CC5F54E24B2C3CA7B41AACFD25E554880AAF406EA4C3C6E21D3B550B040FB1952598A7E8E6488F +E38288B2AEB6C4718338598A2BFE4D2B9D14C65732DA304C16FF3E1F8F03046EF095B65FD609DA87 +EC24A69278BFE65C905CD0329F6A486B8525B7EEA4F7AE56C2633CD83543269E8ACD6D71F500D82F +DFBDE7F7F7B1AEE67328549232E26CA55085B6E84D9E2E7F74068F93A90C4654F2F396E57C5F76F7 +E61CBBE523DBFBA6E76638BBA3064DA025A79E3A294FE7F1CC28A3B4C57DD6FDC48E541A85534B25 +E1BC11B4F78019457239EAEFD4BE9007D205F1D985F389DB22400B279C10948551A6B4A17FBDA0FF +C9428B18B43DC76EFB15FC2182216F1B60B4E344A03AD6C00F141EF99F89F24C819C3E32877A927D +84C2D006940F39CA8B71E5951673EA9BFD1749923219DE38929ECAA9CE43B06CFA7DA1BBEDFDA56C +61FF6C24F40E59B13870D5FDEB82D981154FAE5D6D5152DE69339359461A41A9713B6BBE47E868C9 +33CD74C75DB71D13BAE4DEC85E02FAA14EAD6C0A253B16C79514657B15E68CCFF9EE6AA385CFF9E2 +C53D9AE40F85C793E4E8FF50B2B7420F4FE69807BC5F37C3E300E6B3C3549D1D3246A2E70F091054 +1135BDF805E0A698E236B6496702D061241687B7B8D1A0E517DF0476DA09D89667A7AB375FD2672D +CBAB8124E511502DDBD08BA04D941DF1CEBDCCF7ED48405CBCC33774A68C5212FC6F132641FF413C +984F8B43BDFD7B1A2A3435F15AF07EF4970D3E4A0BB947C181E9CA27CC14A35BD1BD096875B45873 +8CA244F88C28728B74E25CB8C4FC1095A56CA75E4569AD3082EF194ADD11350DB3B74B96761D4538 +596FF7243B1E1B724716A144106E080D42036444FD472998460CE9ABBD05B42AF9389AC452BDBBA3 +A13A96890025789F16B9D92251FD3B3BEB2C61EDDB370A20456E3BFE5F4039E2557C451C524F8087 +015BAF3FF05F51869FB97512968BDB2B49589C1C7AF1E085250A47657465F480B7023E24C76731AC +0EAB6704123D77977D3A2C4C56B691346EBE589C619C04515D34F81FC6A17527D5D8319013C5D4FF +27CC3925E24C99231AC7FB9EAF0BBA482D3B75807AC85D03CD09DE5D9AE0B07B7A813F0449786500 +0AE8A7E00080300F0AB8C399057EDDBA273DD2E1B2A0DCEFAD3B332E6D4AC1FFAD846167DFD70E03 +46DAF84AF292D4F424256ED5AC4E104F80697050D50844A708EAC9E7F7784FD01646F3BD0C595CA5 +1EE6BD607D254E78ADDC5E15C3B6AC4940EC865A5C23105B6BE09EA09F2C05D6D76960A843B81EE4 +33977FAAC3CBDA85CDD2F4DB7C28293A77825635992AF8F3B38B4480D9A139B1662345A8ABE1634A +77496C3F57597D2985E9E54717AB2E99CA35789441BCDDEDE9A9E2106B401D9684ADBEFE40D607F0 +75C179E9CC03E59E65430DB70B441D43DF03F2AA6FF06F224B6E455B01C64FB89EEC9103E48453A9 +749B4D602808C7E408A8903091D85E06AAF635D0D529C3CDD1B8479AC0F4208C284BB678A547F2BD +77BB17C86D4560434F7AD1937760A6AA55B614CFA9FF8C9C96561AE6C8F2121C4E20237428BC51DF +2099B6C49E3EFA18E6D439E6E6981E746EBB1DC461259D8EA0F8099C47CCA27B2D982B72C9A07CF2 +1B3C05D6E26E6E286E348B8944078E24809F9C5F3D014B4CBA02533F5621BFBA1F0EDB776C634746 +703C9F73BA89B1960A496420C68F54E5B901A6D733D7ACC79F275FFFB253F389AA480084468BB34D +A1E797E43B7F6E8CAF5E8C93069A3A2730E57EC39B677BB73E3F07C2055599F7062E53B37A5F0099 +907D2ED87FF7A82C95FBAEB888033BDFD67BA3A6031A4CDC56CB1E4CF5B06B46E16D988BECCEFACB +9E1C037023D7BF5CCF5D65AA66A17AB361BE7981F132A578F3ABFB97960A6034F052D9D5AFDC0679 +782EC90F240F943A5F9A3D969ED7399254FF67D89DF668F7C56FCEA1FFDCF20481474AC8495D3AF4 +B6D7EE093E369C057F0B70858220693B398ACF8E8143558132E4391405E30A73937C53402E459F4A +A3539CF7A99A3F51C0307D045DF8B77757E92EA2F51BF0BB4F77D3904DD355665870C2B59F1ED7F8 +4FC71FDD7F0B6C5D3182DB77827CA6A2060D2B8C83C4EA4A432EF43A4D0A952CC6CBBE52A9F0CD66 +1A538973DE41FFE9C5CF55F2506B9EFEE51FBAE5E63BDCF5528499A47C031163C88D3022606784DE +2F46A9C9235AEE3D4F71D4959B0CFDC5B7E78C8C0A8F9DC99440C2263DBACB343C5C648577F5610B +50EAB1CF7FD02419EF3941C7CA0B0E64EBAD4B2CB05A0793DBC38F1946D44767BD287F5E9779C611 +CA0DAAA1E7393DBE0683C8D3455CDFEBC0E64B54B737E298DDA605227C0C4BBA87AA3EC7FA6EBAEC +39E6EF2537D5974391D31739D9FC42983D81AEE44711C823F35F8E2321AC74943871739D2DBE9748 +FE68592263E7713F27E0D49B9B5CB7A4E55DE54E6B800D15856450FFD3AE5F287B12AE4F438B20AE +9E27E6CAA00F3EAEADBE08432684FDF9931E925544A680182602A3C1997DE5D0630BD5A010535E66 +E1C123013D23966B3545C7431C39B97295BFA4099D14461004C42C85095EEACB9B47C593BC6DB863 +533A8619BAE09095DE8ECA432D4DDD49AA600D277E75DC3F5C6631E2A05382CB007825FADB77438D +CFA78E252D79B6A196D5164C2FEB85D75ECA25FF80B1D97FE10E87960CA0FC47C41D3A213BF141B4 +8BC3AAA93FA86245064668394665BFD52D12C3BE4CE39EFD8111754398A944C3FD1AFA98EC337BAA +AF899D35E804CF416AD7FE45FFF13FC6354007501043F98FE8428DE8013901BA6A28711A2CA85A27 +0BB135B72F1D5026E8217581860729E94F2F1878A0E96C59E9F62714FB5F8F25003DFC7347E99007 +8A9A331CB3A6A535BC61866F02513DEB982C4A13ADBFBAC3FF70A7335F40D5489E48E5EDEDEF1619 +1973D932479C62183B0E25EE8C4F76D4F1AE45DAEA4A12AEDD9EF81D248E8D19F8C8A5BECDD1EA1E +98783EB7A38149170851B1942C96C53DE06DEF80913BFC04E539EC67C110498D15B78268853E5C72 +F485F8A27B768569E54241F6115875E2973292CF48FF91D45EBED627AE9F0766D22201B20AFDD40E +5B17CF337F2999E0BD15B86E46EB3C18FC12B7DCADCF9DD50C6C7E3F37E615A892DB3F57E250A072 +A49F7277DD6A2C8042698233D35A699B17ECA5DBDA6D250ED4A16FCC893BF0DC2E33FB1EBD7DEDEA +3C1C39603C8B7E1A5A833A8FCDD5570BD088749BB232615366687962C7E56ED089CD7B092505CAFA +5A80F503C4CF337F07ADF0D106937E25670839D491F7BFF7A523DB609D126328C16113ECBCBF9C40 +04904427A108618AE5D4ED809F8CCAF72251104C94EC5BEE21F91B179D31DBA79CEEE5EC7FF698EB +84AB1D2D1A624F58B3622A78844CE51498B2CEF38EAFE259D22C7BA61104651A862008BC1DDDA58C +C45F663EB26428DAA85E7785363A69D2790996EF5D9621D53042F42F794962FEA46E46F37B8AD1FB +76FC8D5CF2146843F8CC625139C75FB42DDA71A752BAC48F294E4C0C8289FC46DA5EFD9C91BDA6D0 +27518B7E81E8B21F755A9615627D5812ACA674D1527A1185EED4E3C628196E7D0759B1CAE6B9B7E9 +01E9599A65230F1EE469CD33B9BD9C104C44E3C1AB966C9678BD0AD78111A4E0F2D07A01A038CEDE +7036D0534D684A1562A17AD64A00F279200C0371B1CBA61747671D2A21D3F9646CA290F6B82418A9 +6FA177C6278277504B7FBA936325F5FA124AB018A15DC18D2C5E8F93CDEEA52BEEDB78A57828D81A +3E6C38B9FAF3DC4EB7273ECE3EA4482A1C6242A335862C2C3717F9C9ED95F77B140C4E1569B2192F +C7DCF702D0BC9A50428EC406F8BD0CAF886B4D979320D3E429816D88F7C7146D960AC12E70F2CB7A +9F4E3E366665AB3F1B4B6440F55EEA26DC9EE0096BB7763731740A537766490C8C174723BF0EB40C +53701AAD12B21D436ADCE22203C1053A9DC4E9F17AE617888C4B4E6F3A720E4E6366BA628221A387 +D8AB15E04AD69387C310D3528BD2FAA5B22BFF3FA494F5FBFAC4F771C9C7402B95580C5AC4BB3AF6 +92A70CB2C851FA5CF1173EEC3EC29B5A05A0B728BBBB51D3B7AD8B0AF17A1563E82FAFD93F8B7118 +1FB7AFE352874F4EC6D334AB6747519AB8E847B7BCED33EB5458A828E074E74BA621BDCD03FEA604 +7F7B6ABDA01FC7514BA1AFF0D4D0C0CB8F4E42D5A87E395D9ACDD02CCC220C157153422018725846 +009A3ACD8C8CDDB66BC6836B4026FD9F526AA275D06C813179E5924F26A25094E7BDA8BD26AFC4CE +B41D8964D4FC4AF1DFB0595BC5D6714C32F15DC7194E9A3A73013C45D8FA55CC0550A12D9AAE8E9F +F199FA28EFC2426D8D1DEFB93A65717AF3EA8E2D5B4AA8EF0EF38E9600F7D4E7D9F1D67A2E63ECE4 +789FA74B159BFE2F91C19B0378BA52E93DF12830D99553B6618645E26126842AB70262D96E35E5E7 +50ECA0CE3458B3E51BEE2F21191136DFDBCA39BDC07939E521E4F492F392DEBD029C1EA237BD89AF +76BC89F618D530160AB16269FA6B693CF14BDC4EC7C630025703C5337F61458FA09104EB15C7CB20 +AA4C9BDB7CEF3A09F25BC7F3149951A7CD75372993B80CD2112F7674CEFD6AFA764AA3486730D2C1 +897A264D82A91709FEC4A21E30D812F558451804EE6F3DEE2C4C437846BCBDA07C5B6CBA1D94AF02 +9163B7383CAC6E088AB1DC14ED3743EE77E26EA7AD3119A76C0B5F925C4DE305CD7BB3A09A453947 +5B9BD79BE28FC462D8718CE05F9D94CAF3387BA55E6E447BF81A9EDDD3A34E17BE66BC52B0C0BB6F +86F6F008829173816D205182ED2ECED319864A796AB65D4E3950288BADA94FA32B6F453AFDFC6C39 +A4FCFE60353A64627E2057D4B379D3240012B3BB0ED0C7876CB83C1BA5EFB6E2A03F340C2B576731 +F848F762A7E1CCAF267EE06D621BC33FC245D0E1547ADC12CC0EB58B26BABDB8EAE9CBFBAB93836F +FF22BDA1831DD01B7346AD377AA298D84628BF1C07433284B0A90FC89F5AEB2651BA2CEA405D4F52 +DDC0E74B871D43F71EB4ACE0D2B401F9348EAC3A2EF0AD295036BF6CF6F870D58E00B619D50EA7DD +77BC28DEF91D805CD527DCBCFDC16C042BF9B874E3B1567EBA4C1E70744B9E7E5BD1FDA6A5FF6E10 +1613FBE58DC46CFAC1A65ADAF65E49757E9304E2AC9A91E0588600C709A61D4231730073A36D473F +518A145E141D0A5A494441B9EA99AC23F60F54F8127B477E1CE698BB4129B4B1DFEEDF10D9E665C2 +47A62F112F5CA30B0AE5DBF3E495FF06EB28EB438CE8AAAD84D5F50FB56A3AF002C23BCF66ABC270 +7AC233FC0F2723DB99D2CFE7D3B3667732A531F5DC315CE74EDB9050BF75D29E6430F57CB6778B2A +CBD57DFCEF896E6766C8FC5C9F9FBD701CD62CACF33EE0FC95E78DADD205B5F42CC63024624BAA0A +B4DD447832B4E1DBA77BDFADD223989F8E958C8D759AAA37930664C6EFEC708116248A2A7AF3D656 +DDEAFD009B7F5333854608E67E5E588A857167ADF9225CF6C641F5E19C3E08678A281199EDDAC831 +B57223B1BEEADFDCBC8F6F25D32FCA2336C808162E8F381656E847FB6CB13969572425AA05AC830C +33DE6E030F86A3A85D2A66A77F103C7042C97205526DC882EA9A00EB8BD5519847EB424C15F808A9 +1652A6CC89B66A5731126DEBADE123C63D88A2E550FACDEB3886FF98646000C64B3A91078012CA30 +904B71737CEF6BECABD43DD702880538F5A70085E6CC6015D2163681067C3D513A8C66032C34A0FE +17A58AD4BC97CA69BF41F11D5E910FDFE9729652D3EA21F8DD8CC19160A8FC77573B1E9CEF4E790A +79D8AD6723B6804E9616466C935303E063DEE29CAA6C3BAEBF278B818C2EC2F13ED645AB452397BF +00DB8B26E115026E256746CD0C78A959364FDE6DEDDCD0F441A61A1EBA32C7BC172BB09512148D1E +BAC9E791B7D51B71CAD2DC9B83B2F99B3726607D9CBE58B499A13753CE87FCDCE21C0AD0528ED0EF +B9B2C927F57C78C626248AA2B835A0791244C5896686A66173EC9F802C4C633A42B086334D2A4878 +0E53D00809247BE64E529F96AD2F8B3922A6097D414DDE1EC76F9552F9B8D58B8E34F359AD792B2B +E50C26DB05035E7497162E7C49C38D3CD9B98D620AA67492BE5AFCA3A81A7080185C7F0B5105223F +1FA77805502A2E8C5FEEA27699858D84A95842C5F2FB68686D59FE24091FCDDE139B6463BC6C7B1E +0E90D20A83651AF00C85797BB9F53ECEC1675C7EE636D0D9E77DBD8F89670F855EE4D4800FF3F695 +0EFF09BBF8A0DAF6B8242840CFA5BA73BEB95115F4A78BCC02D85ECCE0C0F2EF6F328AD1DD6CC049 +5A3315B414A4D61DA50DA46D7ACCEFF6EE56451805D26B0359AF193531F95F6589CEAD6FA041AF15 +3067F88A0A2FECD135C56682DB2B45A71D1FA737C064EE9A4F404BB72A70B3AF0330359393247EC7 +81512482579865240A23CD8479F21C2C44A119EBC4E81B308DD8AA86E60C3DD8ADA50E0DFE8308EB +1A7F201EDE8DCFDA405AEFB47E0E6CA7DDB376DCB21D37F7ACC4D3E9F26B03A8DE0E8940CA3A9E75 +963A389DF8038D2C486072F61C0CEAF500753C7A6352B1CD0338D9212B42A4D3DA23D5BDF44C27C9 +4B88A415A3242FFE2E1B332477A21D2B9CE075EE479C6E657A4D8874A8C53964229310E01ED4F3C6 +86FEF5258EDF3B464DD6FFD7F1CAF473BBE722D60FB14AB4918E93878A8AE4773930B8CEE110F476 +7F42A52D9304C55BE12846C911A10AB9B2E036BF9DFD597F5348D42233315FA80D0F563C388BC253 +2103F05E90DBF1923F229F980A2F4585C7A373511372D07DCBACA583099EA972C03E5AA67E663882 +6DB134564DB993CEEB6E7A6659C7C5C05C310267D5F8A24EEC2D5CC3E3F3C808E6D6068D1A57646B +37FABD98ECB7BAF99E7D9AC4414A491A73CA34C52F394352F6B5A15F0FC4D88622DAC694699C2464 +84ADAC3B1D366AFEDE2A2CD2042C90516A666A19A91C80248B11224BEDDF1A320E230739E755D098 +B6A67315535F4C187CFA67ED817A035056353FC859BF286317996FFFB478A2248B908FF12ABDE705 +402224A3EE5F463DD3D243875C84E02DB968ECA1CC52C75171EA50D6A88CA91327A7AA5795019F36 +C0A19C093A1C9D3723C7568F9D41F2E4FFB712FD47F897703D7A620B586B81936C84AAED61D84332 +B3BEBC4F95B796B93EF7A1F565C494F8A65EDB21E2EE18DC025522EF8E599887CA2836069CDDD889 +88E5862977B7472584303198CCE97EF9F9E1446D1F1F5ED1CFC666A8A0C3A03E1792EFB60A9B4065 +49E0DEDF6ACCDBD98742568B4735A747D8E5DE21E630125AE0C691D054E42199C15B1F80CAFA6E7B +B2005F374A9A5F9900ABB7409CCD50C3AFCCAB1214E6A856F7C7EBA89BC3291801E1343DA9DAD2C6 +ED075C8ECA1423B43E587AEC67E6145272814B3F191B3C285639F9E2D6E148A02DC2CBC0E054D629 +5CD05DBAC1950400A9189316F0265B86A732D302C5BEE8ED233768F237C62600CBAAFF3A110D5EFB +6CC7CA3B92D965CA7C5E8D3E64ECF239FE2507FC797FDBE54C1112B28D4DA44C60AB09D994C5BA78 +D663A2591934CC052BC70CD1DCA3325C66C9CB982E2039F5DB70C848D3DCEF655B1C2CD0CEC8865F +E8E1C0A267BE4F707ECE6F5A3DFCA3CC1EDF92C760439F51AA69A4C1801E96CA4D6EA4AD980258F3 +D15C893913ABCE09101984C61B91D603053E49A97CB82FBA707DAE8AF1D579FD69C8481CB7B712CB +CDDB4D287BE995E32C02B399602A08B9DD849039B5673F1930BEC7BF366EB082D2CA5DB2385C8CC4 +5BE3FC0E31820191A814EBA7C4F23B1938E6C4D800732787CD2CB97F762DFC85D4B798809B5F2254 +D826CA42B32695428D120298B44CF38494E56240B75DF1E41E46E53C44DC505452256DFEC819408D +605FF14D6C1F3F152F2FEA96EA0AB3B472D8704E06BE9F8C3E8395CAADD06D6DA033E81ADE5DC3B8 +3DAFF743C6E9E48716003D358DF63CD7FD3E2F727D1F2D0C29962F76D5C95ED44B6F08D052025A66 +5785F264A3D5F5593677B630E628B5EA81FB37CFFD7A30B7FAD226B6FDC82B0878AF4C0EC4F4243A +807B9839EA62BCBDF7C2E9B30A623876E632E084EBF4A21EDA04FC88A1C07021D0C72EC3E969D449 +FEB08E5826EC20E55B21EA71EA59F6E3B0710B0DDAB3261B4A2029ECAB68C19ADD5174E55D5E984A +4E5F38F592A302FEE6ECE732DDE841A28672C620CC5D687455A5C06FA9FE688394A04F96312ED025 +B7AA6FBCE2925F3AE559CC1886BEECDB70822E2E5CA3F732A87404B1536AAC469989E9610CFA440A +CE43875A70CA51F36CB6F629D9424C1E35A88F92D5DA3CD8CBAE6E8425A36968E21F4F30349749E0 +205BFF8D552837D6FC39532525370BBAC833F75F1854C93FC533A4AA53ADF7008173A70D94A4EBF5 +38EA9E62BCDA7C20E0A073BEE2EFAC34D2EF1D03BABD5147659E50B557045B2EB89DB303749B04D3 +F54B43FED612FCC68206E001A7AFE90230D9C12F74A32C7EDB5D0241DC3A5D51481FD7C8FAE08FEE +263FBCED7C7D911B3A303C835AF5FADFD218F61A9D6DE80485ABCA88200047B094441F7767B97A24 +E8C612590FA2407BAB1E8B56C71914EEF2355DD97CFAFCC192BC06FCE063D3D9D1A629AADC75E3BF +207234C208E7E30663EDD691043065C9CBC473D97C6D4DD3DFF59D6A9ABCDD4412C3128F603160AA +D8F81C6E7A4DCAF35F3A99B4EA10A34375B477C2BF846521A7EABD4D28078E9340452A198F3F5ACC +3DB7E3908939FF6E3709C6A3FD9889439A4AE3E10B618CC92E14B68429A3AD2C80940A1079452EC2 +66F254657BE7D79A2A24084AF73F6DF71FBCD32BF6913A3FAB25F977787F7BB0C3A3E8BAB38D7A2D +B0B4826950643DD1E03BD7DD1FB149A33862A89226B7CB454DAF613128C2075470E42E70A9444A8E +6ECA526345AB48E6F5160BA23B5BDDFDA6049EC44ED1461C7E0DD514B16E2FB285F72039DE3C7982 +EFD40D7F6C8E8F4CF35AC71B467BFC578002E8D2239A2FD2C4BCCDD8AF3D7DB1F4AE7F2D2E0811DF +9D0155BA6EDE50B5F052F14F6AB884FFF244D8806C07EBCB49ED22D85DF696995991A954AA97A1EC +D86ACD76E061B7541E87997FEF0657A826BD88EF3A4A5920462C6595E7A156F453291CA044CED810 +860C3B0149BCE73BECA713040664AD0591304106129600AF71317B0D2907839CEAC99515D357E980 +B1937B6E1200AACADA205421001F1B2F91753E80D2263C56AA164A74701A8D5FD28E46480B0DD963 +A683A1F355D7FB4463C7347C94EA5E2CA40B60B56297CB22D972C5BB10E56715A955605256C1541D +9F3BC5768A6F355CD3B863F0FA1A781EDB49368F51B29481CBB41D4AEB07AF9DBE8F52C5D0FF75F7 +FB6431D37D6AED84D78C778871CB0F715B4F07580F23B586C969C81B471FF6A6C7276F7E141E02A8 +584D4B9AB00E7BD643D2C3FAAA299B1F1E25048461952EA42D4882768A70DE46B213A287F8D31AC4 +6D5436F22A796C05D1FE50A9BC2A928066627A0D87DD57A3AD91DB446404B41557D1457873482005 +EA20916BBE46C613F456C849D46BA79D20627B446B2F49E3FA309AE14F8C420CFD94922CBC0FB9D3 +5A0F7DBEF577F1849A1A80E0011DA8AC082A8C6F61658E65AD177ABDF23EE17C8CF0D26B9FA3A6E9 +4837EB9E930336889767A8D7EA3CE980A8EA95528B004957BE6067CD9BD8E02A0F23CC1762CCA656 +D33412FF45E917FD4A03EB6E8C1F43FDB0A8965A33B4FD26BC24A20B304CA817E88495BA9B361A3E +933717FFB0271F7F70C5D3CBA1E86D0F51BF3ABA194DAF32C35C796627D00C7B2271ACE2463E37E9 +7B3C826CF3DB60028F240F9452CBE08F7EBCC5FDB1BCBB3C327A9F450B9E5671916101D6E3E5E458 +CA31F04D12F592F83BADA2C3683D3886AA3B403963AB5DBE220FEC00037A745839F67A3635DFD3BF +F08F367482962DED88ECF6322852D643A54D5D303EB04BFDDEE9BBA1EBCCBA7C653B3A613A8E719A +DEBE3CE1BD7E754E5F4977E863E3C2D388A65227B451D4F3A4F94E06513CBA4AC1F2F511613FF035 +611684CCC461599000E546E4D972CA6960E095A526E4735A23421A4C9B597ECE08AFA2753592BD16 +DED93255A1E33DEECE3C5EB77B94670E8137F2A4A4B98AC193258E7DEA5DB8408A806188F2D1DDC4 +40CCF0E9A6E2F0C78FDBD7B68DD4939D2458C1965BF8BED4564B32462FFF3EC892C03B11D3EA813F +AB4CFBE8D3016329C5B7E3DFED0F08284D44AA0B7A2F6BC96EA4503E8EF52A64C22BED6B452581AE +8FF8917D53976471941A9116A2D878FB2541B561767ABD4E31CCD8A590CA03494C62AFFD64EA0A1B +C779173DAD84999C7A8D844EB1259DE7BB5B25CD023537A474A524EBE4660B22568949E624D8FEA0 +AD37F4CE1EC75955EEFA49C6BF1803BE87E9C9865FF3F6B8525B8C15FE8835CA153D27E6C0FF0CA5 +1029A7A9185D25F0F14D86FC797DCC1F99EE97E2054B9C2A2E06FDBEB8DEF6CDD368BF23A858D9F8 +C1DEFDCEAF1B4A8DE5EAFC604CECCF0D285BE00AA912EAB66EFF4D37AD2EFE34853BBFD87CE09B18 +749B489943EECAE7887B006FB827D10191DAD18466CD1F86505879310A8B171F902EA0C26A388E13 +B53C700272CEE2BFB47ACB58247C13449C6BB9D01232C32517358F1A3DE064D43C18F8827D53789C +CF3CE2EBE78949A6ABFA1A6B8414CE360A5E22AFB7D1DCE6F5A06182C3B984B4F9BB1A905A9D5A14 +83750A1DE0A857CD5C06945EB7D4A2A6BF1237F32A154FDC06D51A703D44FE052FD3C53E9E8F417B +35D1C851F9203A8997521529F21AD8498F96930AA77EBAF82EE02A57BC77C792D9F220294B45F48E +A8FD94E01CD25645D36D168923562F3FDC93CB79DD4760DA0C103C2675722D7A1B79FCB4245ED12F +A0DB52492C9CCE58B333CFEE822812F7DCA68E802C451B5CFAEBAC608B950386B6C58239D1C62D62 +4DD5D15782FC552222CCA06DDF387B373E32C3C2864C63C768350C37283760F3515A5B0AFD66C48A +B522EB3E808C061F5CD6BD96CD18C9839D30508E7D4EDB88E8F11E31E10919B16B7971F06D7877A0 +58D8A4944C84FC6CAEDF3341B48B6E0D3C7B85D710E0C35F5B5053CF4B4798B3778CC28B2DC7AE0D +F3A49F9F3BCD8E95D746C35C3F47D68B8AA35D97AA08E711B5FBE70D1A623C82541EBDC51A827D0A +69E6C049087AD26F256EB7577F58CCFFBCCBA5A95D093DC29464C9A38DE95BC6B1853963B2DEB0B5 +7AD1248D6F1625E115EEB9510B5772AAE4E3C866657DB0B3BF0E0AC345E116F8D4976B770876FFE3 +748C36165522991F46A36F193DD1A1C94713673C7E4C81582391B636C72DE94CE6254374F99B623E +5686C13D8A8322E83E11BB0B0A896C6A8C2C4F756C5385CD7017F26D23F7C3EE97372C868C8C9155 +81723BB6B76B4C3CE8998E4FA6CA40B633DFDAA59BA902A4952DA90EC4FC3CF0F2676ACFA7F76F78 +236FA2DE10FD3545357215246BB7E527F277C28B353CC6D79DCEF21BCC8F77603CDD58A2CCDDBE3A +9802F941CED8E035313875319548C41992A2BE939A17CC109426E33825AE59BCD17CB19F50D972FF +CBE7D9B4B0BB095303D9DC9D406696C2508D6CE99E11CF00F6461147E97449ED5F486D480A86D3A7 +ACECB7E9A945984724EFC21C5079B1FD03ED803C2DEAFCE3327D2D7827715FD65D9506216C88B0FA +26935E95C64114A51919D419038B1A7E9C1E829FBFB53275093752DF19891A97F3CBF7719C1FD6CB +17019A6D2D25360ECA804C4B35172662CC4769D2B785C6C87E5A4ECCE31704E59F71263B7C3CAEC8 +ACB4C7426EC25F11A0042323EE6C3EEB04284DBAE2C770BC419DCE79BD4560AEA41571C3B595F525 +60191DC7A8FBF63D413A77A0905E517441B16C2B501EA2F9E99CC38D052679F288FDF1894542E3A6 +6989A0090185EB2E75134BFA3D9147C3DB8A621D9D35E37786853779E157B47F71626D6B3E633005 +9159C17596C1B87FE2B4FF47ED9D78FA4C2160077276C8B58CEF5DC030B4A5D83CF257096C047FE6 +4DE307C598B815058E72D5F57DF5C369E664E137DE29349E2F9DCD8C9F4EBA6E765B6327D7A20DFC +B20711273FD8091CBA605C4C494248076F7E03DF65A6A50164980BBBB708741E5BF6056E6F996DC0 +7FFF408C5B8EAB8DCEC315E92873228C805D4440A6470E3EE3983758DD211C9CECDBFAA4C9300CBA +00608A4B2404A3C7AF017A3B7E67F39F0B51ACF950D3E75CC7BC2B8D3480202FA958E8EE0B240501 +5232EE0D264C7CA02C18CA45CB3C2DE322D3EB7F00F9455DB6C5B1F4E59C3E95520EC36D7D903CBB +625D70B54BF6F8255E412604BBB29FEE026CC660577F91DB1DB4A613EEEFB20CF7AE3CD89D565AC8 +38416B01B5DE4FFA5550D17FB51FBBEBE21CF1D56038863EE931B90DEC2E211ED42BA92EC244D4CE +2C4EC5CA87A026992772DC2AF754FC982B94F36EA7B7BF75E0ECE90CBB2A6AA1A012E8898BD679C2 +3CB3827C35D5D02F0569C7AA82615D4AA67518ECF668D3B57D6EF1A8013424AC2268BA0D9A74D588 +79EDCF6382A89D397864940303EAEC45A38304BA8B1CB198967AE23EB81054BE74B16909A405E8A7 +799CEE3C270FE2A6DC50BD7370B6B2C8FDB9A87D88D5D40348D3984E39C693B6F4486D994778607A +80A3122872DD65E40492107C71C3CF708A9717E9EEFAFBDDC239C53AA9645B711038E59C8B861B37 +411AB2039BEDF9CFD00F08D9C5D76154427FF5DD39878CECC5D7BFB3F1F035087185C0981F3C2139 +BE84872FFAD3408531C4EA9387B89F5E3EC779E8850D50992DFDCF9132BC551E985943B07618AC10 +D1150451F0844C0DC41D6E17EB508DC8689EC726400D5A7F6FEB3CC7BCE05F09228B7CB2C5393664 +D8DD9A4B96B1020EF25D70AA2D91CAE93AFB5F2BF0AA18CA5C599FA1A708EF35BF8F7FFEC9AFC1F2 +42870D028B2B1459063B493943EF1283829783E1010242E5CF4DA39D93D506F3892936E7D6CF1124 +70A521D397438733D053944CFF12D6FFAE8246F20618684F263715AA98E15D72A526383E05C23214 +B78338E5B476F0981D90056E6E5D0DB66B1DF2298E597B2ABE1D817E18BEB056E65EDB4234342D96 +00470B1420C9210419D834E431B82F58608C87AC361A02D0F1FE4B470A3D71E0D21BB87E1023D428 +E23D596CB9E1A2184403A16E36E644BCCF9BBDE27290485057E62827283E7380AF786BF395B3961B +A5EA469C315763FA59E0F176EF81985F38B882DE56A74D128E256D1B89939728E55A92ABA21A6B78 +44FAC1BA7BBDD8B34A18194A2984B000380FE9F672E83EFDBF276FE797A325815B0F25CC95C97A9D +ACF56D583486305D7C9E51A7E337D14E3B900333EB38FD93A99587DA2341B10C059C71CE080FE753 +3C0F059FA40E560AF9C4A41A4BE6FB45846FF8F78165E10B4AD40F264BCF5596A1E8EF8CB6EA4B1A +3A5C69059AB1563843679ECB2511A90E8898F54295649CB73D277760D8D04ABACC7BCC6E777A0530 +E2067CCBC08673F9C8C178F9D672AC8A15E5367F0C5651B53E75E0CFA57C931746AE1A679C246D7C +9417F1CD89DDDBD1173C2F880B7B3847CBCCEBF99F7122E832D7C9BAFE2B54CBAA1ED48158DE3F36 +238B76B0E67644A28AEA996DDC006F6AC0242E4B667639E7523CBC90A0561193C1AF34481C2EF402 +EE43A82E1EBF4E3D601BB36B2D95CD93550D61CEE7A94E72F6D30C32C8F91A61E964B1F66ACFC398 +7F95D4028F116E9A9A8474AA29C1C1A984BE0E393BDC41DCEF6A6F1018DB60D52024899D8EB5D55D +324D73F39BFA47377B9E15B3B06A7585589FCF52A54684173E5183367E7B0952DC4BC2767C4C6247 +B1D6103E52BC7B7EA6298F454C5D97AC575F19C10ACDFF4E10C7D3755CFAB4200CAC545269FF1D8D +B0D607C7AD47F40DDF257AB4E7D0750577003C13E4941960C3DD7B0774DDAC18E8ABAF8F53E03CBE +F6D57B44F24CF821014C064278FD51B3427593D17694B4ABCE81F49CBB984C5878CDF0C38D1ED7FD +99B0B9A3BD8D8FF6219588B3B8FA59D0CDD1D9B2F65122AB45E48F1757467B9204926140E3C350C5 +A927A2E700173053EC35D3F1DA2D7258714C97FAA857F0898917BD94625C6D1E2D77138EFCAAAF51 +7B17FE187A2212C24A881A2C6A647DEF6376ED80AE4175C5EE80921F001995B44E49F0D33DD9075A +CF33BB03671C0BCC34AD5784AD1CDFED3A6D9BA103B3DDC1CC2DE74DBB576A0277715275218CD19C +A8899209125266D8BF1286F881DCC2C383749D1E768D670F4099F7DE959EDFE852583183C9111601 +2881A56A24AAF020EA45CD5F39660DEBCE30AC1C7B8CFC60387B1B0C3E361BE612FDFA9F01B7E4B4 +A18839A2C7E0E393EBC5AD9A8A4EBC316A740C1C295D9EF5F4DFFA0667F9582C0BB837B142C4CFC6 +B1798E9476D0631111033B8BA75A10FDC800E2AB1E0E829632F869CFE4737BE9E2800759EE0831DC +7D1195EAF80555771981DD6DC6606812D92CB8EF86447F5F6C6F626D0E265C67E52A6319189EE349 +D48E49DFE6A9E98F76C414A1E3217AE0A215A17E54AA498F4ECDC50242ACC7E2322F63BB2FF2189D +057E7354E32A3ED1803116176B9B9D0129930F919E2FEC280B2C8924E49E7BB75768A2EE1DA8ADBE +D4E3589906DF1B923AEF84C1BD327438B731012E69BB0D43A1842CB88BB54EA4516477F704CFEB28 +6E3EA483445AD4D74586FCF32E96D366901084365F693A53C5FB532FBFE7BC0CADC404C4985042D6 +8DBB90A6DCDA3531EE324D558A214F935CD9FCC9A0CEBE9B5FB0323F4B3820529599EF48EE068B5A +CE85004FEA2984F0A86F5AC9D56163BBFE1142B774148F1EB0A4DC89C3349052533A7DE66729DB24 +41B82F8F7360111DACF69293C9B281A0534F3E9E9224A75C49A832F28B2E497262475507B6DDFA9F +01CA0A6696E3F5AC7EA68595EBA0C2EB8A47813FF936D84AC1B23ECA7AA2862B793CCBB0DF9FDD49 +31BEF354CEC12FBF478559FEC29F81ADF4452E83963E56541D31F3691C93A50F0BBA5E9552C4F2A2 +3A6E53060729854A3DD71CC4308B91957DB19E66AAA18FA67055A950F1C2CFF78A03BC1A588CF624 +696068068719AFB1001C4581EE072113882D9052B21E355D401ED8CD24D067B99E616BDA5A0A5A93 +36FC499632B79FF2FD0DEFB096EF46B75E2D4E0F48DAEA239719FEC4D9A29818F5875FC5041A9EDB +D26CAF0ACE14CC80BA49BBA59E918EB3D8F1E541AA16026585A2F72DF7D83541816DE46981FB3EFD +0C30E458CFAD04C79421AB7C4925E23AEA07F9F018431C790002596D26BD9663B51B699DF53E4882 +CBC34EDE88EB55045B889B6062E35FD1E018BCE785157B85EC3B9CA6C85D4B16238275385B8285DB +012D8FB7C9F5B946A41D7A0FB878FF72C39683144D8A007CFF631B43748F2D5FC690300F9BC0C837 +006B92ECEBE0605E8C3A4A400E18AE8997D1B45FEE10068E247C647CF82C6DFBE5E881D511FFA687 +B7AEB78546BFD07D5F7EC242DCEF4930D8AAAD8C6152B6642AAC325963FD147F236BB850A9966573 +9D06CDBD7CA79A527DCF461E33F22BC9C5DB00DA2BD3DDDD8C99D99793BC98282AA8872FF96C3942 +85D82D9419EB78B6AE37A5F519397700F75D624A09BD255B576E955A323E784E8FC31131F003B0E3 +024A4F58FEF2A6C043796201FC425482E1155E229D1B2D43EF7B0D22322B22EF5C9A1BE026A1C3D3 +75EDAFF99597E1E5477952A4E8D2ACF5D014BC00DC2A272FA62B6983E27D228881E2EF2B8B95A681 +CBE90C5FDE16331C85222FE2A16F0A3C3000A63E2E21666C0C119F8AF89A543D37977069A5ACF155 +6324F05204CE8CAD50FF4FB630D9CBBFC324DEDA584AA56A99D3A76FF55BDC2C2EA3A021361CCD4A +83C7A5E2768D210FA6DE889FD48A39D679C94EC3C99A8D33FF11377DA7F6F1B71A2A05B302ECDE95 +4F26773F39AC881542F0D0969C3995C3519A8EF70B4220D86BF01BEECC6462855E7B686E1AFF1CA9 +1FB8FD8B4A69E10EE0C2AD94ADD44449506F9B6EF43641F2026EFF6E605C670560C2B74706FB949A +A7E8CC6A2D0D6207E457E7FD87EC1B9092DC68B9143947CC8ED14AFDDCBF8FDDA228A76847F96802 +E561F67CEEFDE45AE587673983FC04C96744DBAA83F2DC838D633943C75DCB9E6410474EB27B348F +26E505F0AB90878940E846C5E9F3C5FE8C3558C3236B1B88C405716949B8506841CABE1717474BB7 +C30DB91CDEE33B0F844811762FAEC535BDCF84C1C747CEF9B1FA61D2AFB5A81335BC42C06A94D7D5 +9B7EDE55BCF6F9867AEE107555CDD084B7684C2C87087475A39A9DA6347BE281CE5635A4D07865BA +98CE26C1465B1AB0343F49FF37B4D0CA9F3BB693D78DC3B21925CB996A038DCC172527FE57C07460 +EF39C07D4396E7FA970D9F22ABD21A9C794B64AD96762C7428F59A8757C36D6C4FFB23216195A04C +2A2C2E7B10EF7193931544D782FEE4B91E01119C5553BBC6252270A8D8C56DD62D448F5AD8DC69CC +B45E1F17F0AA1E445129DD00F000005B23D38DE93A3BE55A4C041947F36B4E4536E307D0180553F9 +2E46B743881CB5D5386C48C7D5F84C2BCD06B9C501F78C7EE61FA23516791FCF4DB278AF688A2E60 +10A56692AD92008497487EDFE4BD5FA083FA544138B20D6940020887E35D46E093B71F7A04A67460 +DC8116B4D4839625D7CA6959D6831CD93F81AC4EA2709036DD738364FDE71113BF22EBF13DFE1642 +E564701E6F0FFE7511EDF03FE448C2B28C64FB7D54B94CA576E481FA56B2B18AF10C71F699B6BFD4 +7459CDE1869D0FD306BF489A6F42E5B2F05CCF55BB6B9526973D19CB134CA7F13F1DB3716F8CC217 +73A832568C16250B5CDB16DF24BF81D49F5B37018BD310262EA7078107868AB0216CEC83CEFCAB1E +9F2C665A31585CA04DC01879CAA79AAA5AB201B516F7052B01B16BEE5606098393B0E5D9F9E5E3F4 +EB20F63C958E796DF41CF28839F5C62A0431648745D7837B519F3AA36BC6C08EF040CCF53D9B6D8C +0C7D1A84D707EC57A3C6AC9A62AB37251A01A5ED40FDEC6F5BE6E34C6A91D058319439778A2EE5D0 +363E2E1F33463C33327D05FFC0CBF08D5BC457C7230448972FB9B4D0D782BA7DBF10D3FFEF8BF523 +6EC16D4DD6D0D870D9D5EB5C64C9A46A4F583D4F831FEE74B0E5B33A09ABFD4444929BD8F638CD72 +EAB99CF2E9551DF427683964A592E49D186F285258C5D5F62196A98532421D73E3495F82695FEEC6 +E1952C562D546B28618FFAEEBEFF03A57F4D855021F85B0C7BC37FCC6DA9AECA099B646B99D41896 +09D3FF2D56422F8C37E97640293EC7C90E3380887836F4938FBF495CAC14FBA5648D89282D8D49D9 +1AF73ED36581139D8BD42551E263E830EA3C6EB381D85C42D74C50DB0CCAEC03F535ADE92128A016 +0E811C34748309AF7604919B66CD43EB5CA975302DCB6076FEB6BDD6FF55976FE990FB0CE9ABB11B +195403FB26E3D6C6A0DE1C5BE79E171A61E21F79EE8DBE7A832519813EF6B33EA098C2C32ADEA219 +AB2AAC8B093F40000995539D1276D5F2EF84CCD099B71FE4269BDBDB6A8D59C86F7D2E3FBCCF8773 +D0FAE97640BC1AD43CB4B992BFADFB09DBD0CAAEB8CD9DA264187C4F97300E9A6C9DEED5525479E6 +05C65AE336CBBDF4E5D7F79AD098F977285E065579B748FEAA97F2A753E1F962FCAB68D72BAA8EE4 +FF6691C23E31BC0F3E981A96FB440404856AE1AB32A7205B17D411D8F21C8C93B704D07EC594422A +BC368CDA2B1610CE6A973F4474E12B78B532666797F5755D269772C9F5400B3BFC6C58395D38527E +2CCCF29B56123F7DCEF3BDE5DC1DFC5B0293BB125085B1D2D929BC3EE84F4FAD571A4991C3DEE03F +2DB3A3097E52B1A7D5C73CCB6148EAC62E8E36DE9A71C57638C6E4D5D9DED18174E8C390E50B4A5B +913C074EEAEBE390B214B3A68F02862B9A296DB4B409769649E51D738CBBDFB7702E15C73C2AFC6B +C37CE15171F4E822CF20EFE55D9F061AA43E648989628FF79E65932390CBB15D8E621333B18B11C3 +BDF96F841D7434E01AD501FEA964A75B248A35CD9DF9A37E48A1E5A09C624B93CE44F0042FA00D7F +9EE89B9F7AB785E9C718CF6E7228F743271C2C9BBA17E5208B920E44E765D99D86650EB454B0FAAA +112753AA1BD3A24239E9C5FC47EEB1547AC9D23731B8DC48B9707830DAEC60C8D3790BBA1120F776 +4EFAC542CFFBCD5C05F9510B27B2534B704ECD36C8B041FD49A96881302FFF5B0163A2DD09C751D6 +D6AFEA9170A4F4C4AB8D46E62F763FE1BDA51DD1CE4A27E772F3A2869155F762FF26B7AA6FCFA4F1 +292E56F03AAB6322BF867E7710C34D43B5D85B45AA68014AD7879EED051B1933E491496E3E26D9AA +8B80A07BF2B94F1077E84A9726F08199887D66DE7A307BF33C30DD9CF3DA188088C03B2BAD09A217 +6B110DB2C868B53DA9A66C85737BA66C93C58A259860E294AD0191E3A72C73F40B0BD98699AA08DA +F03587B78F391F3A4313C58D9F29B53C70785637BD0C58310109C54091AB0A34CBB0C478613A7AC0 +FB8F0A8B4645AC966395D8BA775262CD291136AFFDDF01C1D83DD4EB3B59CCAD18057FE7D92A8CD4 +A58F22508D9FD7CF356571F701BBB23E749BDDCBF8A317FDA0AEFD952BB18545610FFAD3AC143D35 +1B8DB3F66293375E0E50235F0D0466932181D377EDD32A5F0FFA4E22B5A0CB4F343D9A7E4A342E9D +09DFF6C697630CD3971802C277A5590B8CA94BDE6B38446C794D072BBCCB724D5BC208EEF1B018D7 +39373BB910D668882CAA779C2D686081DE6A2606417B54D7C20E0E7F722648D893E4EDBAE8F00D6A +6DA3712F91AE860C756D1127D133AB828E9D80023B50B162C5A1C5CDF70CCB3FDD7EA060ED20838B +E1E50C4094C9E79E1A0187CDF780CAF45A725964F004253E034C5BE46BBF89D94631F1A33BAA35B8 +4FA2A9D08481C6674126CD96ED05DCE48BDA069D902D6836D5DFBA701DC0F98A863E64F0E312145D +8DC0B77F25B43AEC729A1243B45B08CA228DD6101CAA2AC5ADCC8EFF84A4CA3F254176C2CC711EE6 +C273835D0FD3528ECA2A976B88E51FE347FDB60F32370B66D338931D6581630ED586F349C638960C +31AE4204E89521A96E1219E696B913DEB2AAB7A3B022D06F34FDFCB810A04E60A4FEBE284C2F063E +0AE9EDF87704921CCFA193BDC912B747E13570066223A49F1F6E2AF0D4D65DA04CA876FF7A462FFC +9C0BA2CC545C3BD36DBE762F32B2D6BE5867C59F479195C92440DC165098B74EA5C3AD93CDF2D410 +B04C16BC7801E7956F4E5107450787AA592493171C3628E6B8F49D4F8429EB98DC52EF025F001387 +BC1A7093F7A99F10B5D2D7DD8BBB393BF6E56F08F4F7FA1A343F220D5A1EAE7168C74D41BE1DC1A8 +3BD65B72B982F4F7B34F24F97F9EC9A91011064031FACFF2A14921A32024385F4E061CD07D152E74 +1BF97156D951A342488FA7F5EF934CCAD13E2753A0AB7A1F565C2F7F6B349DF03BBC25BBD972A9AD +F809BB5C5048A8CCEF9297B2ED3324D18867F293CC66E88B3A39D107B610DFE79A3B4E83A96D3D52 +A17FE8A62C9FDD271130148366942C9CE57558D023DA5F7501319EBFA33DE9E6D1E76D7C20DB8A09 +B657839DA99F3D8143F1EE6253A3295C9651FA4366547893C2DC7ABCBF4BB7609DE5D001E0A36D9F +FBE01F7D0903B3208AE8547E2E5F14EC1AF4C2535CA8F4EA37E3F3CE172C7A1E8308995B1CC23E6E +81190246BCAB6E755BF868D449BB02A2AA87C44C9CC0F571ADC72547CEECBE104BB274B8AC16DCB7 +5D5F458D356466B921ACDEEAE384E2EB1DF6EF393B41B9747F0A4FAEB4AF1928D9AD6FB7E06FDC62 +1E4C6FC98CFB43F88584BD55D9B97CC9549093EDE586912161931162B1B1D52D0443260DABA02AF2 +B4432100D5506546013DA703573FA8013685CC798CE501960093DED713FFCCF89CA2B9106390198C +29A00864108CDCC1984A8BAB53919028C01B26ECC7925E38CBE6CCA8978EE21C2B06E7B3E48FBA97 +8E2A7D186E563C088F84AA23178B60E4729EE87D67B1091F3B6973676C1CBFE6530EB773C62E2C24 +97014AB0E8B71A1F4E86A378AA26591511BEE3CF3D64C94848582E1354E1605B6457823F2C5E640A +D3802946BB2E7E8E594E8C04B430C2385DD40746CE8534F50842E74D7115F3DB0C72D1C9C607C657 +3B094AEB73B7A79876CFFC3E2F8C9FEAAA07D3BFCE05B61F7749A8793BE90CCCECA2D7077F25E899 +D3331FE161A7E86C842495D584C6E4A0880B2951D8A13B88C4672080A0B1BE36BF47C3ACE7288CFE +41A8C1BAA6F0814A947FBD6B3AA72B6C73A8C578CA51CCC96F2352316C467BB960E981F2B6485BFB +44B577E71EFDA16E7405954BC7C9F0759F5A9F1EBCD2FA9CC9648D5831A68887F41B15081A204C24 +B4B992A231DEF9E698D4C3A25B6F5474F5BE6A601F2D337A58A0D21FF37FD91EB86D1D738893A03A +69F0CD743F611CDFFE69DB2C6ED0E4611D56F803BB0DC06E7FE85A303839612707647B1BE9FAF8D6 +84122CA9E5CB8BDE2936D3F4FF254D31529D7538BBD4D35539489F9E7316F24214B996BCDCF1818E +749A71CF0E8845AA1E2A58AA62A48E02BA4564625D20AA220EE719608521D7D7A7FCA0BD8904A401 +9819D371F3F59D46C1354E5FC1A6E5F79B20CF4ACA2BF0F2DE73DA193A6F9ACBFE0B4731C4BCEBE6 +D96FE822965DE965232282A3A130361F188B3AABDA95A8A2790D9240BE008B6A6DE4BBFCADA05B67 +86B9BB8E0DFA0C30043A3B07ED46277E07B9808422C8ED16758B9C396F4EA929D769785B2C9568E5 +70A83B989B25CE200F1727D41E2B702E7F88F1784F4C83FA60A74EB26B2DA95126E508ED519A61CC +151DB6804F61826C5F86D8FA89D06E526FED97A0DB88EDB432FF32C1ACC9B622EEDF601081AF7B96 +3C9CFC1D13E4A9C74FEA0A1C8E3D8653CD92A944D4CA6B0D306619AFD503506D77732D6514F604BE +4610C2560931BDE0B40939BC1D126B0E97F72AE1B4A9252123B54F7A27E0CFA4425B4546526FD741 +CA77952B10D13E0AC2E32006A903808FF0CD013F936238C74CC75FD915244C56A8412F37F0134840 +347699508D6F3D7F3203A25B7C70100719582CD588590EE34B3AB13E255B613A6D00386A0104CC5E +D2C646F09A88888D3751651D5646C5227A3C80E8DA1B0A331121DD2429F1F4775D30564DFF47D01B +BE2C6C72CE4D1FD9A2077C04D2B0274B8916F6A9D1A4A6964A534F47CF241D5A8E34B23F85BE9ACF +FC2FEA961F277539F215F8728D6788F67BEAF45502839BCF23D8763C3949352F00C579A9A4FC408E +C625E310DAE61512DFE6844E82D36A2F81709E1F05B38AE9C222ED62C961EE63593CED7AAF73CE2E +D3667740C77B309B93EEFE1B4BA65D48575A66BE86743DC9E5D3C2FF418D11F7F211B86E827EE1DF +C3613E7498030F07050524536D1F8A94DDB6698BE7B963C55CB3F74B676CD815A7B3DF4B1A0EA2BE +1B0B9A11FFBFD5B1FA49668AEE14629316AF436A0821C20BEEF7B3480847934A99F6D85B68F4DDF8 +859A754E009428AF89A90D1852C220A607FF0806E8080726EDC94D691D214B4521C147C4273AEBDD +BB4A697EF16448CD9B2FC95293305858DECFD406B89B9F3FDAE2AC579E80CF321EBAE5701FB2F7CA +D8ED04B4A63115886D45D6120F69AEF1A21D80AD3C2D35D2899F1902242B96CD349E0AAADA40F7A1 +1282B6B52BDD97708E58DC5E2D22D1153E5FA3F3B300BCDFAF98DEC2F4E3C82A1C85F985735F3987 +4F557579F422664E07CBE19DA680EFB0FC82C323EC5C4644C51709AC8D674608A8043C91E6C7988D +430F10BA6CE1FC7FC0604FCD8F723895250AEC36CC35B3FA14FE2A0D24095DCC30B2093F2298F5F0 +A97676A0BE66C3DC9ADACFE2FC0F721A20E945AFC1096A619075D5E9A264C796EC6C90EF1AEEA8DC +089B44FFC13D27CB2370070A52D4416C53F364393E46EDD7EDE00799960CE6E0D57E4909E88ADD64 +BDD2B0EBE2D73FA6ACF8B40280DAA0637E705C65AABD523B8815F22F23E9FF81E7829C7E4BC980C9 +143AEBE1A04DC0D253396BBB7268BD5AEEA356B610D5DCEE03135E00AE34388251F31714A1C40E18 +2652C48CDA2211A22CB6F02490E69A44CECB169754C53B16028D352E0119F5D5FAE0BD7EA1CDA647 +12A6147374B64244E21E9EC9F0D1381AD22D5B6212B26C3F9AA5F6045F25DD9F5EB4489EA39B1945 +331AC70510C5752557DE21D0A6CFC1EB10A98FA867B76DA6E4249469F591FD154D39E89364A43DB0 +07AA0D7A911CFAE6CE2B557997FBC44F55A27F622BD7B8B10EC9F5D10F2649A646FD964AE1B111B3 +5B46A252C4DEE44E7426EB5739F24E8A390694597DB3A1FE7800C97E59558322F0E49A0CCE2AD94B +1E2D1026AFA771723E3F523916F55ED866C9FB4A2F759651C613A2CFF362028CDF9D38F05D4C7C60 +24C533E930B64B099FB1AF04B01F5FB9CA6867E6EFF55A772C5391831059987E10CBF987E3F378E0 +1329F73D54DC0484177D3C3C06F67397955FF1CA4EF8AD1606B70455255D631A7D6EB92BFDBA14A0 +FF28B2ACE7E81AD666EA9B3A0F5A6BA3B5DFE35044FA4B3D8ED956009C60E98CC132F2E84967F4A9 +8A67B336D5EE7CAF7DD1F74D1FA08619941361FA7312CF225D89CEF97E864C8369EAFAB94D97F056 +5505D825972B754F6729596EEA91210B75DD8F645382ACE36DE60819A02B3B48DD00F5485F9264F9 +FA926D732E2C267B0BE8CA98526F124F97EFDB86132C5EF16B103908172FC51F286FFE45FF253512 +E0033F037FF182BA536A9EB2DF2D1DB257D9C86C46E1B002FB32AC70CA9462E6EB48994752CEBCE3 +9F08ABD4F4B0889283E55500702185A841E328 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndResource +/Times-Bold-iso1252 /Times-Bold ISO1252Encoding psp_definefont +/Times-Roman-iso1252 /Times-Roman ISO1252Encoding psp_definefont +/NimbusMonL-Regu-iso1252 /NimbusMonL-Regu ISO1252Encoding psp_definefont +253 283 moveto +0 0 0 setrgbcolor +/Times-Bold-iso1252 findfont 67 -67 matrix scale makefont setfont +<50726F63E9647572652064652072616A6F75742065742064652074657374206475206D61696C6C +6575722074E974726168E9647269717565204E657467656E> +show +403 361 moveto +<64616E73206C65206D6F64756C6520534D455348206465206C27656E7669726F6E6E656D656E74 +2053616C6F6D652032> +show +220 439 moveto +<202020202020> +show +220 508 moveto +/Times-Bold-iso1252 findfont 58 -58 matrix scale makefont setfont +<20202020205072E9616C61626C65733A> +show +295 566 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<4F6E20737570706F736520717565204E657467656E206120E974E920696E7374616C6CE9206461 +6E73206C6120636F6E66696775726174696F6E2073756976616E7465> +show +1647 566 moveto +<20> +show +1659 566 moveto +<3A> +show +312 683 moveto +<6C732020206E657467656E5F696E7374616C6C6174696F6E5F706174682F696E636C756465> +show +312 739 moveto +<6E676C69622E68> +show +312 795 moveto +<6C73206E657467656E5F696E7374616C6C6174696F6E5F706174682F6C69622F4C494E5558> +show +312 851 moveto +<6C69626373672E61202020206C6962677072696D2E61202020206C69626D6573682E6120202020 +202020202020202020206C69626F7074692E61202020202020202020206C69627669732E61> +show +312 907 moveto +<6C696267656E2E61202020206C69626C612E61202020202020202020206C69626E67696E746572 +666163652E61202020206C696273746C67656F6D2E61> +show +312 963 moveto +<6C73206E657467656E5F696E7374616C6C6174696F6E5F706174682F62696E2F4C494E5558> +show +312 1019 moveto +<6469616C6F672E74636C20202020202020206D656E75737461742E74636C202020206E6768656C +702E74636C202020206E672E74636C2020202020202020202020202020706172616D65746572732E +74636C202020207661726961626C65732E74636C> +show +312 1075 moveto +<64726177696E672E74636C202020206E6720202020202020202020202020202020202020206E67 +69636F6E2E74636C202020206E6776697375616C2E74636C20202020737461727475702E74636C> +show +295 1191 moveto +<6FF9206E657467656E5F696E7374616C6C6174696F6E5F7061746820657374206C612064697265 +63746F7279206427696E7374616C6C6174696F6E206465204E657467656E2E204C65732066696368 +69657273> +show +295 1247 moveto +<6E657467656E5F696E7374616C6C6174696F6E5F706174682F62696E2F4C494E55582F2A2E7463 +6C20736F6E74206C657320666963686965727320646520636F6D6D616E642074636C20706F757220 +70696C6F746572206C65> +show +295 1303 moveto +<6D61696C6C657572204E657467656E20E0207472617665727320736F6E2049484D2E206E657467 +656E5F696E7374616C6C6174696F6E5F706174682F62696E2F4C494E55582F6E6720657374> +show +295 1359 moveto +<6C276578E963757461626C65206465204E657467656E206176656320736F6E2049484D20656D62 +61727175E9652E204C6573206C696272616972696573202A2E612064616E73> +show +295 1415 moveto +<6E657467656E5F696E7374616C6C6174696F6E5F706174682F6C69622F4C494E55582F20646F69 +76656E7420EA74726520636F6D70696CE97320656E20656E6C6576616E74206C276F7074696F6E> +show +295 1471 moveto +<2D444F50454E474C20717569206E27657374207574696C652071756520706F7572206C27484D20 +6465204E657467656E2E204C61206C6962726169726965206C69626E67696E746572666163652E61 +20646F6974> +show +295 1528 moveto +<636F6E74656E6972206C276F626A6574206E676C69622E6F206574206E6520646F697420706173 +20636F6E74656E6972206E676E657764656C6574652E6F2E> +show +295 1640 moveto +<4C612070726F63E96475726520E02061646F707465722065737420746F757420642761626F7264 +20646520636F6D70696C6572204E657467656E2028766F6972206C6520524541444D452E494E5354 +414C4C> +show +295 1696 moveto +<76656E616E742061766563206C6120646973747269627574696F6E293B20636520717569207072 +6F6475697261206C276578E963757461626C65206E6720206C696E6BE92073746174697175656D65 +6E742061766563206C6573> +show +295 1752 moveto +<6C696272616972696573202A2E612E205075697320617072E87320696C20666175647261697420 +6D6F646966696572206C657320646966666572656E7473204D616B6566696C6520706F757220656E +6C65766572206C276F7074696F6E20> +show +295 1808 moveto +<2D444F50454E474C2C202072616A6F75746572206C276F626A6574206E676C69622E6F2C206578 +636C757265206C276F626A657420206E676E657764656C6574652E6F20E0206C61206C6962726169 +726965> +show +295 1864 moveto +<6C69626E67696E746572666163652E6120657420656E66696E207265636F6D70696C6572207365 +756C656D656E74206C6573206C6962726169726965732E> +show +343 1984 moveto +/Symbol findfont 50 -50 matrix scale makefont setfont + +show +418 1984 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<4F6E206120E0206E6F74726520646973706F736974696F6E20286465206C612070617274206465 +204E616469722920756E652061726368697665204E657467656E2E74677A20636F6E74656E616E74 +206C6573> +show +295 2044 moveto +<2020202020202020202020736F757263657320646520534D45534820717569207772617070656E +74206C657320617070656C732061757820726F7574696E6573206465204E657467656E> +show +1779 2044 moveto +<20> +show +1791 2044 moveto +<706F7572206C65> +show +295 2100 moveto +<20202020202020202020206D61696C6C6575722074E974726168E96472697175653A> +show +294 2201 moveto +/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont +<63642053414C4F4D45325F524F4F54> +show +294 2245 moveto +<746172207A787666204E657467656E2E74677A> +show +294 2289 moveto +<2E2F534D4553485F5352432F7372632F4E455447454E2F4D616B6566696C652E696E> +show +294 2333 moveto +<2E2F534D4553485F5352432F7372632F534D4553482F534D4553485F4E455447454E5F33442E63 +7878> +show +294 2377 moveto +<2E2F534D4553485F5352432F7372632F534D4553482F534D4553485F4E455447454E5F33442E68 +7878> +show +294 2421 moveto +<2E2F534D4553485F5352432F7372632F534D4553482F534D4553485F4D6178456C656D656E7456 +6F6C756D652E637878> +show +294 2465 moveto +<2E2F534D4553485F5352432F7372632F534D4553482F534D4553485F4D6178456C656D656E7456 +6F6C756D652E687878> +show +294 2509 moveto +<2E2F534D4553485F5352432F7372632F534D4553485F492F534D4553485F4E455447454E5F3344 +5F692E637878> +show +294 2553 moveto +<2E2F534D4553485F5352432F7372632F534D4553485F492F534D4553485F4E455447454E5F3344 +5F692E687878> +show +294 2597 moveto +<2E2F534D4553485F5352432F7372632F534D4553485F492F534D4553485F4D6178456C656D656E +74566F6C756D655F692E637878> +show +294 2641 moveto +<2E2F534D4553485F5352432F7372632F534D4553485F492F534D4553485F4D6178456C656D656E +74566F6C756D655F692E687878> +show +294 2685 moveto +<2E2F534D4553485F5352432F7372632F534D4553485F492F534D4553485F4C656E67746846726F +6D45646765735F692E637878> +show +294 2729 moveto +<2E2F534D4553485F5352432F7372632F534D4553485F492F534D4553485F4C656E67746846726F +6D45646765735F692E687878> +show +294 2773 moveto +<2E2F534D4553485F5352432F7372632F534D4553485F535749472F534D4553485F626F785F7465 +7472612E7079> +show +294 2816 moveto +<2E2F534D4553485F5352432F7372632F534D4553485F535749472F534D4553485F626F78325F74 +657472612E7079> +show +294 2860 moveto +<2E2F534D4553485F5352432F7372632F534D4553485F535749472F534D4553485F626F78335F74 +657472612E7079> +show +294 2904 moveto +<2E2F534D4553485F5352432F7372632F534D4553485F535749472F534D4553485F666978617469 +6F6E5F74657472612E7079> +show +294 2948 moveto +<2E2F534D4553485F5352432F7372632F534D4553485F535749472F534D4553485F666978617469 +6F6E5F686578612E7079> +show +294 2992 moveto +<2E2F534D4553485F5352432F7372632F534D4553485F535749472F534D4553485F506172746974 +696F6E315F74657472612E7079> +show +294 3036 moveto +<2E2F534D4553485F5352432F7372632F534D4553485F535749472F534D4553485F666C69676874 +5F736B696E2E7079> +show +294 3080 moveto +<2E2F> +show +344 3080 moveto +<534D4553485F5352432F> +show +596 3080 moveto +<61646D5F6C6F63616C2F756E69782F636F6E6669675F66696C65732F636865636B5F4E65746765 +6E2E6D34> +show +296 634 1 457 rectfill +2109 634 1 457 rectfill +296 634 1814 1 rectfill +296 1090 1814 1 rectfill +280 2167 1 924 rectfill +2125 2167 1 924 rectfill +280 2167 1846 1 rectfill +280 3090 1846 1 rectfill +showpage +grestore grestore +%%PageTrailer + +%%Page: 1 1 +%%PageBoundingBox: 18 18 577 824 +%%BeginSetup +% +%%EndSetup +%%BeginPageSetup +% +gsave +[0.24 0 0 -0.24 18 824] concat +gsave +%%EndPageSetup +%%BeginResource: font NimbusMonL-ReguObli +%!PS-AdobeFont-1.0: NimbusMonL-ReguObli 1.05 +%%CreationDate: Wed Dec 22 1999 +% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development +% (URW)++,Copyright 1999 by (URW)++ Design & Development +% See the file PUBLIC (Aladdin Free Public License) for license conditions. +% As a special exception, permission is granted to include this font +% program in a Postscript or PDF file that consists of a document that +% contains text to be displayed or printed using this font, regardless +% of the conditions or license applying to the document itself. +12 dict begin +/FontInfo 10 dict dup begin +/version (1.05) readonly def +/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def +/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def +/FullName (Nimbus Mono L Regular Oblique) readonly def +/FamilyName (Nimbus Mono L) readonly def +/Weight (Regular) readonly def +/ItalicAngle -12.0 def +/isFixedPitch false def +/UnderlinePosition -100 def +/UnderlineThickness 50 def +end readonly def +/FontName /NimbusMonL-ReguObli def +/PaintType 0 def +/WMode 0 def +/FontBBox {-61 -237 774 811} readonly def +/FontType 1 def +/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def +/Encoding StandardEncoding def +/UniqueID 5020947 def +currentdict end +currentfile eexec +E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89 +699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641 +2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2 +5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF +9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A208511C6D0C255B9A5BB2FDEDB4D399C6CF1 +94FFAC236883767C0F68F4EF84EE696B677DE704EC3B097384F2E673A1F51692B7B260693738C211 +9F7D90FFDB21EB715FD5B8134FC87DBA320EE54C2CEC6A4D6BB350555EAFF2EC4F84365CCC0802DB +B3BD0E3F0D9F858647DD637725C2CAF9557FDF842A0DA6A0CA0F1B442EF8EE6CBF2B03858468A466 +AC5883CBBD3815B283343B39205803C02C917D06825C09E2BB14609FA32C28D720C0E14A4B12D4F1 +25FF6281FF324DA33A56FC49987AC7D3AA206540F8127273FFE9A3DACFFE2B1C269D3DB9A811578A +C7D532C2EFC18376F473FBB2B32EF642B19CDEC1D6DE83643723E3C6DFC87F97A7007B6081894BBC +45C955B7001EB36211B26AD7A3D07459CFB33F9C54A40A360CB802FD202C8E93D4DB888B325CE246 +D02D1220ABF55CE646DFB45F07CB848406E470362F80CE4C02D98DD845189877732744CC16C7F566 +9F77EF096EA55AFF98AA103EEAEFB971731EBF3782E6AB725D4E9E35B2968689E8007C038CF25B6A +E69451A4731E79AC22BD268F56942A233E52D71873E83E00A1874E04D3B22E72FB2D0671AF81C698 +53C389B51F4A257373AEBF4DE2DA1E4DA5E2CA88941F81EAE0E32D982064C8AFDD7A9A600D56D736 +05B9463C6240606B3361BAF22AF74EF89AC804A5793BD512DA2D13F4BB1B73EFCA1E621ED2A65D66 +5AAD0AD228B3B7E3D90DBDB6061E172B686E92355A7C7459D83199040A368B5697DDC3B81DDAD341 +6FF4405E1096B1240EDC18A0E9985CA55A0D697972BB11E9F1BC30765D6775BB68C69704BE200EEF +4E11B78ADDB6229D8FA49A6B1525ADADF17122C0FFF51A08AA7AED158724AC4352EBB91ED0C157E2 +4281BDC1FD610195F495E87062A8C38E0D046DA4067EE16E81BC5F87E583315B973184E474064482 +9B2A52E0D37E249BAB31988B906F891AC904D1BB8901F0673AECE60ACEDE97B8DB7935C6488ADE8D +FD898027424AA85A11A3DA494498B084133B857017A6D507D70A3421235486EB3CF7613C59139FD4 +DCB92EADC60BB6225D9CD0599779217BDAF4813A453989B2E56903F4DBB83D83DF4837C86BB4C3D3 +CCF98F07A23EBBF7AB5687C3E1E6792E40F92A7A466DE352294064537505EEF3F9C308C9EB94506D +B02CFAE289F10005A6E42D2DCE43731A7AE368564B2983038DAD6987F67062199018395BC0FCAF28 +7A2B040C71F7325FA1E9A9808979B2FEF19096B98B8A0A728EB98F2BA3D33B49E3C20BE992822C7A +1BCCA5B4E4D1099D456D8D7D83C57ECBA0FF21428024F7572A1470317CB8CBC8679A974E13D88C68 +1338C68C9AC9557F97784F4E1C8C2E61F26023ACF46232CBBDF3C0BCC5583B935FE9FA09A562129A +8927AE73988DB0F7E733C6561CA7C9716DCA9B88208A715166F2FAE6D5EFF289A9B2EDCE813403A4 +16F243F1B57EEDE7D81E10C2DA4065A3082BC92A38B2457368EEC9C3C17296CB09819E9E642D7365 +F9A6EF430FC7DD611EA5FDBDEDFA72634AB599EB666A5DC178B0A0BD1FAB042792115EF3B6222C12 +41DCE36CB38B738F68B1B3CB489FED9E53315553F3C5C3BBCE40451E47B7EA53FD3D3ABA6CE0AD22 +5DAEE734BDFA3BF1D81C1B42C6D856A05D0924E03F7627C5EB24D7FBEA3BD85716207F961B56803D +BE046E81ED5FDC378F9CA52C14FD8544CA7C539201BEE06487EBDC30FF3B28E8264EC7FD5DA7E080 +65B0A9147344CE28DA5182335875E9F8B2347A44E33DFAA167232A5C3E69E8C5B58B7C7216537827 +C936F5741B87FC68753EB0D4A466961D0050DB59DF3195BD3379F5647F8CFED35DA952D7CF2DED45 +EB442DBFE992711D22EB228BDDF36B8D7DBA27062D60D2271EA8E8412F4290B58F5BE26FF06F0559 +872F9DE4DEAABA015EAB4904BA1F509F6D517C6E897312DDD571D769BC474FD378AF4360E8B1F103 +AA75F48721B9E0BA589319E15D74AC0B03D730C3EF708C7C504787483F134EA6297097B46D2680FF +8AA50B7A255563C88D594B912F5574564A1371463674793E4834AF11D14C7991E7FDB3A6ABF8529E +1A4F10CAE79C60D37429579093DBD041ECAF03824DF9C007E96F45595A524B27EF8774A83AEEBD3A +7134AB4435C80944DEFF5C1CBA921B0A41B9651968581DA4834B3C0E6D4DE13C1E792FCEED26A72A +DC4D9E3903661D8803DDB58EB2B929CE31FC9F50A694116B00AC9F3EEF53FFDB1ACA3394BF111610 +38F39917B022394C75A0D467D64B89A44E5505DED7D9C6B8BA6BA098F140C9C00E09200EB4828356 +A2D6BE9EC1D5524B09C06D9C6FCB5E2808050A339B5E5FD4DD6C2035A48FE9674520901EDCAD107F +67AC8C8E508E6003011978D77ED225F361BC0F86A98B6120EEAFB73F7377DB1E7213E02D12C330F5 +492511B4DDE08558D75D5B8AA2D56A3111DCCD257EE96E3446EF1C76F000C8916C4CE261425ED9D1 +5B58CED128DAA6C1300466E7B152BCFB5E6FAAB2519B8A98F26B29F98133AF886A0AA7E586A090BD +A1DC6120DBB5640885C609A8BDADEEFE5DE0DA5B75A8A29E92515E86E7E66BB29581E5AFF8CB6551 +D8D1103DF60D558E7987E6F56126A13DB2C9A04886C655064E68A0A20D1B7DE24DAD22BBFEE1B7C3 +C208D4FD6A58DE78D6A0A6126EFDEE3B1A9713DEE94069A9F0A2B392A2F391C4C75327803B53F252 +CC9EF0323F84929BA4716C50385681FF5B4ED54929821594F9026B7C1297941B178C3F8A704CE097 +60533DBC6CF4B18AFBCBAD039ECB2EBDC7838A9410E7B227924BED7123944675A5DBCA388B710F8A +F6048B03DFB713F881EA0F3B191A5CD989EA150B979059C8AADE403855815D8F7980CE6288F47EAA +37C1097D33F13776F08779063C5217D7408D9835AACBE5C071EA40C9AE6DF685F4A9827B828815D8 +F3A672E73A418E5CB15684EB6C6FE0998A386E124D76620446907F993BE16FE5AFCEC681F585601E +18182EDCFD3024062A3082AF97E803C47D32229D0A24596CF7E03F18229FA631175699E2F0D60FC0 +9C4F1954C5D12D03BFB4395F0E5EB6C6877083807D91D93CA4177A6B5A8D2AA500131FCB670E7118 +73F8A3C77575EC93A3ACBA37EA117DB268CF10D04AD0F079484DB124F6DC14A50AD3B0294F7157D0 +837D8F9A6060FBCB385606066401708C041594E0396A0BE4B8B66FEA141CCE4BD29366A986ADB98D +9A6935C49C57F8CD415E93FF8AE0DF75E463E02AAC68DF064C1B789B685F84E15E512404E065A39E +9E8F5568A7D97671AE1602605FC7E4933975189837586FB1A55007FBB0E91382A629277C36A190BC +85AF49EF3F0F38D4ADD2B5DEE09916B79690EC83473C63E92CF617617A66DF472A49641DA10654E3 +AD3880D060B02A4A6C75B51E4E9917A2B6D8EFDA12D59DE5A8E222DC7E82F02F23A9D3DBF637154F +719B14114DBB102BE5EB76B441D7E9990EF6420C2E80942C8AED5A1D0B19BCE115B5929AB9E145F1 +496753DD6B1798324F5EC1D0C7F26FC3045D7BB46A14110C99BA07A45EC16002CB754C0BAE7A1A88 +EB387BB345FA70B0A38AB4D532C2DE49274D4F86F2582728A2CC54B4C09D26C0CDEB8FEE6A42885C +6207D74953CFCC583ED82DD7C0F29D35BDAE5BB251B8A2D4B1DC97E2264DCE035E359DFBADDE84F7 +37EA6A59C23D1A64D963E635769233624F7682EA34636B595CCD064AAFF3887D916867475731BFCB +F7F96D5E5E1FBE6AABF454C2F504EA4E8EB382911560195295C87793D5F7739AD7EC7176E126413C +D4D1058EBD7D6EBEE14BB94A1ECF28B686411D91E07373E891F78C4C0A05D2E8D90A8AE2614F7FC2 +63A762D0F43485473A54C31726F8547701D4A38D20565ED1707847AED9C805780F062B847E668E15 +565CBA07A72B0BA99F03FB57D26FA26FF579C30EED0AAB6FEC1B5DBEA81AA88F16F0C9BE869505BE +18C1CB79657D91D6706E2A3F0BE9920655B93EBBAE2B4D0B5DF6BE622C951F2CFA42AEDBF7AE649E +2150FE87CDBF5C2685EF36051080BF39D864573A45AE2648AD97662B1F69787031B9BC43511FB841 +55ECDC3D91E2475D072BDE6A5207ACEA1E0D2ECB1DA8A1BC4BEEC335A5C7102963E84B97BE741C44 +58ACC3D72A7E53B1F08C955F33EDC3A0DC3E7308270C0F7FF814B111459985733C62E8863625A551 +837952F3CBF32ADCFD9F345E14B585B23ECC440775310654DAF7F41E56FF45F89701292019A94BF3 +0EB2D65E14B1A1D6BF89D4CC43187ADADF3F6E03A90ED01E5D876BD3AA56E5EE84DBAA4DAD9824DE +9984BD45AF96FB8A56C010B3C3A3C6139D58E9D69D9109DB18561B55EAD6452497840B9AE90C749C +155B6329716F0152A7AD52DBD0B8A25B9995E1416681F38FDBDFA443879B5C4C25AA29E0DCC07DE8 +BB161C36D76EF286EC88D57C74BF44DBCB4FEFF771D3BD82C8F4E233357C48E516EFE3DB9E60EF16 +8E2C45B54651DF9A5ACB5F1790F7929BCB16CE5E9F6A43919AD287DBC8E12D9F9E97E5DBAA592879 +1A5A02D39D259F3CE273A870906A643CC18D86E23F115D2A35DE6926053D8C84B940B362E7DB183C +4905060316B269223DAD309EB5AC96DEBA757BEA45FA3100F77F4765334EDF3D659E09BD1A5552DA +492BE9174DD406F8353A059ECFEE3709422940A8C369919EE1F22F7C02412C995FE93DC4559D32A3 +155DD22D3526D89B16D9ADDC30CB7ADA6E52D62C5F2DFD142D4D7B6E066671EBAD08F54917E31704 +1F410CFD8A3243F8B39459C418B7B7C6494551C6F6753A94072D09E0D812351D62916383C6E061F3 +5ED864923002007E626089772D269B298DCA2CC1F25D9BE43FD8AD62D554C16AFEB7EF6E5DDA66D0 +5A810F003CDDCFD2C02FFF02BB61344968091F67D3862C1499409ECCA137B9A2A9BE314995B818AC +CDAE27ED4AD583BE29DDE4E8C2400C5F8152C85709AD2A4737BAC768FEB70CE81A92C9657DDDB2D0 +BCF9169D272A063C75C150ADDFCBC2F5F2503DE3D13231AA8CFB396DB38E80197A605F6BC20EFA1E +DE40CF424CF221218D51BEACE64A3DC88377E4F3EFE43DB4F4FC0803BF61764104CFF0B618C90311 +98B094E20B0FACFB94240B438B67BA298E31D3F4E31FD190E48BFCE27B1BE29D36E765E7D295E96E +DCE09094FAC43B87E294818FDE9363FC7DC5EA36A1497EE25762D02DFA00A9BE53F87ABE62E52ED6 +F59818FDFCA643042EC13D670DED1980413950EE43372D31AE2694B83DDA42E1FBB049F7E7B7E69C +93FFA3195A2462423DD2C022E5141783FFA07E192AEBC5070F08B23AEC9142EED56DA74F93BDB504 +78DA55DDD0A9987FEA131E4CCA0EFC51064E4B37632728261369C3FEDACA100F1AA78FB718ECE7A9 +F56296C5FB43781E63F36B0E1D34BB748EFF35E1953941F94D1A9B0FA474FD68B47183F2AC53A63F +9F1D30B9B89C5FE54C3765B43DB403D57994701C133E42B950D9BB1CA202F15B5E590EE75598FAE4 +3D5CF1546572770BBA9A6373F100CDC61DB4E5EBBE0A93E0E51C86005E333F69110B1C8E492F2BF2 +52CADD5B73E7D3EBB53E759353F1EF3C9B8B39C230D13AB7158A5D92EE4C452F81F6DFC18803280A +A023832FD0DCB482CE5AF615C952BC3F7E58F6417D69775FC7C0D5B405AAC632857736ACF32B2EE0 +F2A2C0F3B3CAD483C614505BE94706322F2A2830FC5AB592907D0291ED1873377E7A6158140C2CDB +1B0E27EEC9CA50176102200992308045CCB5A169B61EA0546778B8D280737319046716604945A21F +2A1CB9E15E3A5DB31E0FB5A3B0AFDFDF6F3424B7536D473F9756CA3694DEE4301FB1AB1AE47128F8 +D2B461C051C1B999DBB010E78DD13AFCBBA6F7D5226D540527F17881A18F551B3EEF76A7E28B4FDD +879381A2217EF2FF9F9982E9EA70AD2003B862D7C36D57C5FF9FBEAAB56040FEE973EFC3B34D8319 +1960010110BA10694C17B7635AE03CC1CD087C0B05522A7A791F0CA34022A3F5860B536D9551BDFD +BF560A07F63AA4E687407E5E48584E689591F1B52671213E430A708C06A34D2E1D51CFA6B328A122 +007C81B5EB263B967746961BCFC8772F8502DD95898724ABF369B0877F3313A167F3F714023C229C +5757D4D46FCD9B4AFECD093DCABE52B78132CE9AB6225C9A344C4BF8D96F2C50C4272CB9AA0D606F +013B2642F8C880E08EA2822C8CF5097D2CDB64932FE195ABD5FDF36D3BE123AEDD8BA2F82A8A628D +BE3ED6129DC0FDC4BE50D5574AE4FECC65062E70F4703BFECB35EADE196294FE173EA57938679DBA +6D15448FF44C0D1A903B202439DA93C0B0E612110068F8079219AA89F435E44D0464F54833BEB338 +670BD820D941DF4B31F51B895BEDF833F9C43CB7616DB80F988CE72FD3C12C7D49F740CF85B4766C +0ED398EB837695D102DEC16E24B7475A0F5DDE88FBF2D6B94F126417C811E8362B9CCC52D8891C13 +C10937AACC228D621D4712CB9DE0BAB60EDE2A97E9292BE04E42E6D3425594DF56931A61E1F96172 +6AF6E6891D63B240E6E79E5BF30C052091D681BA1102409874CFD8EDC3EE2BE331676E31AC00F807 +91D1019BB789CA4F5907F4823B002AF3581448C352BB67D80FDFFCD1C5BEEF60523330AA2C045600 +8F62DEB55E69AC2F86369FAB1ECC90D2487954E61117A90D9269A65DFBDF297EBD29C3DD1F62755F +8F289C42A534F59650685F8576EA2FC5D26B99B8E3DCD3F1FEEC73131000F99AA9868EA9BAC0B56D +AE2CF46DA6CC1D18C0AB8D77BECFF7B89992175CBA2E22779C13DB9DF53FF5B1C8FE95E164997D94 +202C37175E562C8622989B075CDCDE173452C064274354D5DB8F7D5A78D48AD4A103B9E47500D08E +DC7C51C1F3CFA7F43C3686A3C24A7EB5018B0F419961564F87E212CE0A0741AC68D6822C7AB9FD68 +85F5D0B2AC249CB7F50E2353CC4B0A6A24562F564FBBC7090C3FDF1284AB0EC615E0B3FBE132F315 +70C8A65C814F93910AA4BB80D516CB70D2E1D11969238E6F022D628FA2F33A0A15C4EF0CE7F753DF +80A8AD9494885A1B9ADAE6C38AC9DA6FB0A61696AD3A502630252AD7B574C841117D34BD20BD6581 +217D977B35F5D04E02B933E1E84F5C090F6615AF484D63265D28517BA74BEA8876FDA332A84AEA12 +E6CD82B94AE10A778CD3A216ABC08495EF319F06AD6FF8ADD237D911F846A514FDBFAA8A1EC8E0AA +9F80F11F1CE615519A4B044F3D1CF1A17D7F3D2174222A5FFA8B39F20197FF6CAF250B6ADBDBF519 +1C525070C8D38220FB501C223F493D80F498621A02EBCCD6EFE914F16B2A435D60C0A1A453E288A5 +3D818FE1EDCA7D55A26A017F2EE47A816E90D6C3FCDF0035EEA307DFB06D2BCCE43458A67354A4ED +B6E5C57233DE4FBE41ED07EE5EC77A5DFADC4032138DA9E1B74428CAD02A913E40152F8063A774D4 +FDD4070E4B8A6C089F199AF7C529C277E902195DB760D81EC655DFFD1BB283F3C5AA8BB58F2476BC +797B2892E94414ABBE96D4DB93E280CF7DE23EB852E7CA954D6682A6F1A4BE0507884C2A05AC863D +2BA73F3B54668397B6C54DC2F4183130AB414875F3C3D8792BF7E5FC4D228DF87748BF0B14178DB7 +E3FFB7891D700A1E9520D778B095DA80E4801F53442D5C073EDEB706A5DB8466FFE7E701ABA9C364 +A37169F585C883A83713A61C9C3BD9336A667EA4E3DB5F4DF6BC6A552BE8D3EF093639EC67E5FF71 +8959F9902477F5AA894ED2D1CD312ED82EE417D95C49C96671B23FB0E1738E892ADFFE62EC1C3D4C +BEB6CD089C98DE8D247DF7ED17DFA2959D3662F105E8386D75AD308480536959F8E6CF8F2C6937B0 +9F2E8137C811327D6B165ABE46C51834A955FE8306D10033F8C2A34667F13A8BA831CCF52C7A21C1 +3DB92F3E77B55CE291F6190BB1D194A33FD73151C3F61ABD2D8A0C9BDE90E796BD996D2D0094DB2B +E98657E751BDEEFE8A43EE4501B98F0CC6D80805189438872A60047A8CAA9039893530A3E5F6BD75 +BB466B25165737C939AFF3EA59BFF4A7DB09C2A5B36B8A1F0C6C5E5870C7C9412589877EF44F8428 +4B8A53B5B74315CE72D2EAFC631BC4CC2E5B71DC958B5A6350CB5F615C3A4502E973622E3E18193B +69572DEF1D02303A375ED60ABA1BC8A179FAA0F221A49078FE15AE13383585FB45FF4D5F3BB3D0F6 +D8BF62E9BD6BAB3C9A7D38C8A5AB0BE57ACDADCBD02B1DC7952D73AEF702D406F62719922BEA96B8 +FDC9B879708E794891C7A0A42F2CCD6812C3F4DB030B5178E3A627C3E77621D312CE4EBE815CD387 +7208FAD92761A5396B67E835222609F823728B1C987857CFEAAE21F2AD5EA9D841212993508091A4 +A2C268BF1D8DA1C650F6AB93995E7C13A3F84DB55748C626FD09C0DA1E3325CCB0BF091E996245BF +51EB486680162BAE63B6513C74CE83B92359938439921950D713C69324A87BCE67B45A030C9CF10A +DFA0A82781D49FF224AC57A23C6CB321F95915C5E14E41FA852F66E1E2044A9E7B1DC3BE9E818515 +D28B2C4D2F2210098C39557067062BA4239F2AAE28816D999955910298A450741947A9A1AABCBD8A +FF3530626089978C87DFC73618C044731B6DB8007739A9699ABC354A6F985E03C11D750B8B9E9AE0 +5436205FAAD1B895B159E2C90562B82A62EA1A7FFB501767DCE2B11C51D55A17529EF5ADF0A0EE9A +96D0E7E89F68E50EED813836531B4B46E9071E84AA413F4135CC882CE832BF78ECFA7CAB0C9F64EB +92C86DFCD1152BB7D4AB33831AA0C139B555967F6346068D5C3351A7A4368EEBD2933E6B9F789DAF +37EF536FCF965C397AF1B7F98AF864B301F3F440B7ACF704B59540453678FD6C1504519481893812 +3E2F47B265EC4F5CF2172D394543D84CD4281165CBEB11349B315A85DEB2D1699507B0C8C110C726 +62EA2959C4962FF093AA5EE6F21F89B3CCB0149CEFEF1855B9A48D28BB363416C015A1F4EA1975C3 +D8807F616C5817C8162536176F464A198EBEE6C97029F15F414275A39B8219128B8C8542E9483550 +7FC2D3908BB0EC375771280B9EBE87E827811418EF93E52EF70546891BFC0FB34969FD7DEA4CE752 +4D9EEFF2B46BED908C0FB2E02EFC1D1624642EAEA1CAC1EB4841E020532E88E59AC890E6C3F44734 +B99722E9816402D1D0FDF8045C5481EC055100836EBFB48E9FBC392143032C909853C9BA38A19363 +141BED09DAF02FDF4E7CC9808321CD0708A1B45270BFFCC3A0D7C27F7E781713D5DECE82C72ED303 +86B02D14575A1A6447547ECC7FAAC1BDFF332C92984758E242256C054656CDD2C45D46E67AEC6F83 +9F95D74E222A6EAE12EFAAB723A7C816D4E42D4ED2725A794743F67597F3DB8CCDDE45BAABC25726 +B851E02E56341EBE69E4D91F2A233583EC816F18A1DECBDA4AB69320F55E730617360FCFB8AC2D2B +737675B406297F7F8C4BC370CB084C22BFEC5FEF02E9AB290282F7B153F0A4B1AE569F1E52371A43 +46A748DDE09336CAD1F5337FC3D7CF0677091E59480AB15021E023E356B0E1BAC6C6471AD53625C7 +0206C338536F4D0D40733AB217E2297F86B593717C61458B6C93A16027CC886A8CFDC01EF19C34C9 +A608B95A84B6A2E31454BC03C10FA55CDCB7B1EB7DC16AC1E93981A46DECD7E7F00638DCAC568744 +69A2D9B45CBC81398727E4ED3DB5DB31965F358D8179CBF934EE2C4D652C9CC211807F070C80E3A8 +222B4C31FFEC8DFB9EE07A94C973462254BC1B1581903EE6F9AD91524A787129A63FCE048B45BBE6 +855826750C586B6B23B805FEC3E7AAAC079576949A06F422FC2C826BDB78AE96135E9E2C20C2B2EF +F6171D610B2EB8635ACAB7C5C5ED9C9FFC26CD54D2FD4CB9E4294E178CECA1E16CC8E3FC06518BD1 +6F4D63AE2B435753538834CDD9D8AE7DE624006CE688938031336351A6578C304C2E5480A3FCB43A +8BEE4953DABC30558B7790C6E7A6F0F9FFA557C50417407AC6A0DDA1E736F7070BC89455FC293453 +3DB004AA9070734C8C2608A07330E421A0220DAB99F8A77489132F6413ADB9EA637F3B75948050E6 +67276A55BEB09D4153DC126BBDBE0DB9298AC799A943D72AFB769BFA1488D311BEB86A907EC9385A +AE4F77835DFFE4389E3D9ADED1B08BBC2B1ED6084B3D1074A326CCBF38E06BD026919107BD03BD9C +30470DB779508DFE0DC82DFFD2DED749E872EB7EB9DDF509D5319865070DD76846C34E4E43691AF4 +29AA40DB4BF2CDD50B275589987D8081F7C5A0461AA5D1455A660178A94A0BA0DCB69C3CEBF5EE04 +26D6534F6F919D9795AD6A0E1A1F452AF3B4CB2EA54D6011FA809132421D111EFC51174E223AB6A1 +3596411A9723079231B050CEDAE7659CF168C39AEA9C6902C2CD37D25492CEE00096EDD63DC7643B +667FDFDE5B595DC54F0A72C2650E1E46990584C78A5CEF9BFC3C5F88CFB0C49CD6CADD9DBA675177 +D601927D75C6902B55AAED0E9E3CB52A577C887D581B3CE6201A1C77C9546CEE5A13B92963337F17 +070E2BF9F5C5E86B84225863874618AA50F4DE855DE567BF2AB7163944ED43DBD7F4BBC0E1623180 +7C43DCB47B2EB694E6FEDCFBE26194D2D9943A1BFE32AA1E5305F5E341EA021F91532162978DD1B8 +C5295A5E7551E2DEE46DC2347C6B32197AF430AF3BB676A53BCA9BD1EA88678377DC0A9A86E2AB6D +E29E3E261BFD5573C66FB5687BA9C0544D894A759866B066E1DB5C66E60AE071CC3A1C4AE40197CD +E4EC723F7B80137619DEDC99AF57A5497D6E03C1C9E672E74F48F6C213A3CFACF2699CAE72345A51 +C71C1D69348DE5BC5F443EC0EADE1E76A8A33066922CF3869E3C1D26A3B34E540DC08EA4DA2DDE3E +EB17C16790DA4EF1A3A76D71D34B788A87838BF2A5A3DB8176F9C097D2320050A79EA6C4A94926DA +11ABCDCD26DBA09FD33F30AEED977E8B5AD928F3967F607628859429DCB4ECEC7DA3411BE35A0385 +1017B535985632639D378CDCD13B00FE537A49FD9EB6DF1E3AAF5C41EBE35721FA6833C2FE08AA3C +FFC3477E7FCEBF9EF9F4DAE62FF78F319481C3F1E72999C8A493EC6EE295316B58A5CD62FFAB62C8 +96E521B678342F04BCE1613CF7F6778CBF5227BA20504500D743270771953ACBD5C6586432F3FA6C +0987BAD33B88BC6C15D29C4B3CC54A9DD72A2357AA5BAEB2CB057CDCE72DC80CC98C62B16AC50B4C +6A7641379B766CDDF990DBB2FC7F9CDBBA755B6E3DEA438FD6699C30A99A8B3178E6D613AA938120 +835E517431D28114BCA1AB745C11FE6E52ADB82B9D3D53A33BCC49740C93017D9531ECF43831359C +5C93CB0E926DB440B139E3125CC2E069B1CF6D96EF68407F32DB517242C3AE0BC6723E560B0F45FC +7F87A5E44E1751C8B7F9F669C24AD5CF16F84FB03BA121B86B0694234D8F2C9C947269AF96FCA08A +78F736E4E04ACEA44C5BAAFDE360FCD8BA6A59724CA86160A5527FD564468123D302DB45173C1B21 +6B01DC5B6D3415B13FBDBBD3121A5493374B3357EFB131CABFE5087AA1D2C7472B0377066B3632C8 +2073C6A846285CC953A8F28E131CF587B35217EE498D9A1DB57B063CE068DAF55D8CC1771C0C3099 +9CA4FDC5D67BE4E7E69418F6334BC6149000821B89A7437CCDF9A6A0ED702D5968F1E04F7E4FE9FE +C9D1E994885CB624035BBC5426CB8EDF0456828F8EEE75BE491B45FAC192A405EBA25CAA4F4C66C0 +DC234D7B417628DA5276C08260BE512B2432256C401A66E3B583E69D23E9FD278CD5F2178544D054 +16B9B4F61A88A4728AF2CEED07C08E207F31D644E8E3BA1E4E2F9D8E30936BCB9C6AEB54E37DB46B +D64F2ECC1021336D0564DF0F18E5A6B6BA470233D8D41FDD9D1079706EA685B6D8A740570BFB78E3 +984BB155C3155C69BCCCB41CB51975EEA1C1B4294CB546CFB03DC31BF86EC3BCB1977E8F94A771CA +B09DE12A82F1D6C791FA7800E5A21DF81C9C8FCDA78622ABE75B54AEEA747AA4F26D563200992E33 +7231A430137C720A17D44F3AD6CFFE63B2DE12D3184BD3E151F955786B8DDCCCB290C42718F3A219 +1759DF76371C2FC177544A6C425CAB14AAAB31628A9CF9D71B5257AFF0D59843989CF0D747375A26 +DC9ED29B66AC2147DA0168306C48C2484C70CA92F33C0C138F92F276F5EAF5EA3082A8A1CB12DB66 +1633C2F71E3B69918F509060AC949FCD52C36498A2ABB77D139DF1EB33E3B846A7C1BBDCEF5DEECA +4EF0AD250CEA9C2751E13EF7681E8FAE0491CFA6C144DBAC1FC39D39E76EB12D3EE9CA159AA77D27 +94F0C433345B135BA632F544082BBDC9471E9FA3AED3A7D465AB7158E8AC97F68B1FBC8D368E2350 +45C18EFCCADEE98778D894D96301F903283C5AE355A863BB0DC5809158F7E108662D04A5C1234915 +E7BD5B4C30F9EFA55E702E54F87FCA06FB321507BC57A1E55CC117E21AA4E3A4DFB77C1A949EFE36 +6D93F2BD827EF8CC16D387CA82AC039F77FE995BE6D9AEFC87F8D809E90C1017803BCFA1C737DAD5 +F1A631EBE6894AD20C70791665E7BC71F21C2C3F4462F60FDE75C8A377CF49BE99314663C6ECB538 +B1BF021B2F2174D2B22CF6FAD115EB0ECE8A2E64097A5FB0A2AF666E1EE13276AEC59FD0C9D4BFF2 +3F71E835984E5EEEE36490C54E077AD7355DBC98BDD37DF29B3DDF8C55480B7349C4D17322418705 +796A8C521FFF920DD11773FC44FC631C7D6E9B420D7965D7F62EC7385F2BE30A51E2D796483134F8 +40AEC71FA19ED1272C27F98F2CDC9C7E54DAB585AC1703ED08F5F9E825564902EFD08EDF99DFD494 +44C21FA6BE16CB8A1B6D0C8A5ABF80A50BB8D055483176FD0AA07EBAEAD88FD694F96FEBD60751E5 +C4D8F9BC747D4F4030BCDF9B0370B7A5E0A6923FF60DEA16EF47F886F10CCEE6956ECF41A21F7C59 +6F3BC78299A9657266807E01762B2B2878E551914CA312C2A68D34CD91E4F5115EA1FBE801346E14 +AE529049089B6B0273E258785773A9CE8E4B6C4211CB7C2767319576758F811CBAF3A3FFB41B3130 +6C49F3798B698A47BFA2E3CA0251C4D90C0B02ACA28C611744526906791D9E157E54CE4E1BCF5B68 +6990BA8AB7897D624EF00EAB92CBAC255AE9177DA9F0D86447D35B452CD2F337147B5D3EBBF2B952 +35778A72914EB3707EA78294B3A3BC4ACB19FE87C72AA1D982E4B822F07B115CADF4D3E7EE3D1BA7 +08653BEC6F0A352A0C33252ED0630E7274961896D461EE8BF523D5911BAC1C8AC763E5FB11FDD217 +4E1F129675969C195476C7A5E18A81BF9A11ED9F2336D5301E3BD32174ED5C933E8C85D6272EA218 +52A6F7E2AAB174E0965F73E0EF89E906BAFB181DBCF8B1F5AA0C12D12C6272753C016AFEC2EC9F95 +41B8757874D6F2E061ABBE8B29281677246305B3C41E90418426C575BAA216CEE3C5EC29B2FDEE1C +77C14FDF940792F48A56AE80AA33E370B037CB28A7373F882022AF378F26B6006A049FD3B35074A8 +65C97D153352ACC156992C00DE26AD21C982C71F0EDCFEB61593BB40FA5F2CEBF23C4FF34A4F4BDB +73CA273C269242D1C6117262B7C47771F2619FE5710855134A80FA8F92BB2425CF88940CA3450F81 +234ABF2B11775929B12CFF86442B2AA0F4243D324A5983E5D1829775B3C7A111D5622D1C4E2B2A2F +982FC8A95F789881416DCB34950A393F4F1720D2212F3D343A17683060182355DE9E4718506D76C9 +184F8DAC55788D7E603CFAF4907DDE965A49C323DFF425FE88C09AA4A4D16283F9B14AB9EF1BB885 +A954034710B4A9DA4C88A8A0932B18D139A687303EE562EC9F656F12F3E8F27DAA9C75DB0FA946FD +0E1A982BB58E040BFC0A49A4AD8CD668493FCB573C849EC5474049A693CBEBD4D79AC7515047CC34 +7A9A7570C90861F3ECFB57B9F53AB9C0D6B05C8C570A8F3C04D58555A45524C98FF091B8F8A422F2 +E0E9E5A7B7FF69F1CEFC13E42F1CA276BCD584516D266BA6838D5E9CA9E9854F50C7D92CAED61AAC +AF758A7C7BE59C3BAA82BF32B691ACA3E8EB171E08AD22C39FBE586A54E6E4DE2CD86B31138546BB +8DA5834B2C6E4838547A1B67E651964E43988C8036931088904BBB589CA901E7EBBC094C0DA81E09 +1915D9E46828AD8596FD0FCA39FF12A6C27A359337F973809E81B2E9E3D43B3146F2516667E607FF +EB9AC80FC95A7B7D4DED551FEE0F3561C70DB2D69ABA96673E39E3397F1C3F8FE5F48BAB8AD6E0ED +8901F90F6CFF24E80CB5DCAC498506C4D01033E497C1241E413B022227A3264DA68BC3F91B35781F +A2D018475C199F43CBA7D3A0D5697B45321BAD2C394B207136E1E16B41794975E8903EF2B2E1C33F +87CF72C325C11EC0B92FD3890ACDF60B521DA32596763BDFCDCA837ADC6F26F129B23CA32F9CD39B +33E64576970DF3C05B8DCA4BFE2F17E6C5678B84D69494F1DBA9FE0446AE6AFEAA1FF245C07916C7 +B7569E6267C42B459435A1D116CEC665B311E404171774C0ACC8DDE96B0D9167C8CC7D99C4240559 +2D745C4428755500EB4719340D2FC6BC215B67823F69FA949C08B5EC985D7AA87C9AC1F9BCC8994C +6CBCE6027B7D1E0C22A83A5DE61DBA05D4AF6884C95F46BA7F253E0B2337E312916E163CAF9DB2EC +56C5425990FE73EE53E42B3BCCA1CF642F02B0C5ABD529B568E9ADFF865B9DC190240AD78AD226ED +884BED3C285B4CB0E3929E805C67F1318D186504D92085764B70DE6AB5AB6990F181BDA50FC31262 +348D980EC76608CF08176C2502E065AC2D8EA5CF9E2D44E2B70A7DDC7B922047C471DF8A0B2087D1 +106B5BD8A830EC0E53223CE3C96EF56E5541191167860EEA58D696EC357EC55799438C90156BBF2B +13A0D5C9EE93227746654ED73EA5B9CAB61DAC5BC690F89C87FECAF9AD03BD39E438F43B81D39E07 +E0422F94E8B096AB38C88BC2E1A043811D8141C1A35DD3A6DBE41620E83C8ED3A379CD80D4F9BC30 +41BB44B933DACA7C5D4427AE94A176829F24B5968B713431CB8BD9F53080832C6B784CEA9B515687 +F121983EB9D9C9CE8BD4FA3BEC48AFE64E643B7BD86D8383D07521FE5D091392BE124CCC91113604 +3824B686988E7C83AEBF406D2DA88FD952D0FA9327F4AD04C55FEDBFBFA76ECAE8A176C516479AE1 +467125B7EB3C9E7C5B103BC0C470946346DF271F8EE19DF7E3FF7478C35EE059297F4BF21A5C7B95 +993BE6202E897776952A7ED0613A5CACAFA731FFC633CAB62963150E86EDAC796026CE02EB235B9F +7A54E0B0C5281567138A612BAFE409A818C216DA8EAC5EDF9D1E3A1E3514AE50735A111B4D2AA083 +4EC6C11E290D58FF340F82F0E079F1C7B3566F2336EAA45BF72BCF88569988DB5F65D4C1E59B50F3 +41E45A899656A0B522847ED567B49CD5284FE50E5F8652CDAC1C076804F2B2185F6A51ED19DD4941 +2E65A0D2DBC844B75E2DF71B009776D9F97A4C6F786EFFEB87A307FB6B912BB659DC2BCC6D509A9F +BDE87DE8D716040A8551B6CCFB7743978AD992D14D2B85CA052E87326138DB196C24593F8F7ECD6F +486F85D1666B9DE2ACA6C7900044EE369D223524664A2790B773F9EA26E0A4CDFD709942A44298B8 +249506EB9B77BC887DC0EF947DDDC7CB3CFC6B48F060DBF032A11884E6C226D9D447A5A458CBA325 +D57E144C6DC295262763E7BB8FF6A0CA473EB7661C12E0E8E23EA37E8AB3387B9E54686F3E57765D +4067E521BC1AFAE52394227793C737C19208803F2F2DA920B553E2AAF94EB992AB17E31B58C15CC4 +AA8A1B444DF5B3E7CD937CF03E1F7FAC63342731B4589F16939D16E8E497A74CDE5686F529E9495E +1603D74875288CF53271DB9313A4511B104F80B179FCF213558970A002E945281BF3AE51E668DD6D +13D9E85152747F562CA0B75DDEC8FE9FE31F8D05B0F59E802888A7A4F19B29954A31108D2F041367 +DEBD6AA1CAD856BDD1427E9EFE89956FE28D500CDC6A0CB80A76902A08D0BC6705583243F1DD8020 +749B257EDF4803BCAA653F7FD6D8B91690995BA5EA3EE92FCD367C11601C6B8ADCEDCE67B16C596C +5D200693AC5FA15D4CC6CE9DF7A71C8A925E99F5085313D60FAD25C1BBAAD28D4AC2B69062D68F39 +0530A976319A3904CEE44DC9451E441AAB4780425440F8C499B81460B5D3E268974145117ED843B1 +71BB14AA84C3A084A7D8E07B9979260675D5CE6534DC176DDB60DDE90F6A3674F67462EF78195F8D +FF74FB5882B079DEE31FE92816F16CE1A70D07752EA25FAF5000ADF79BBE7D17EB1BD2F9BF6CDBB6 +F078CAF97986442680A8FC4121866F9CE86C385DE34E30D8B9768A0136D9EEF79A4B38EE99CBB9A4 +D32316564C9D56996E2595753EA71BEF684834FD030D38BB100E2332B026B046316A53270A96DAB2 +182E994E91262FB03D1AFFBAD623F1689228409884F91DBA153030870A7BEB2C7EE2DEC51875B137 +33B7929041F8D23A94904BD54DD4BC9B432DD0C78DD81639F46D686FFAD39AAFBD1B6C1A37E248CE +48F23E12464D5379B4AED0D50B5A41577E6ECB75270E9AD3EA7D0FC09DAB271FB18B51DCFC0069F1 +5D72546E6C51049F3425AD005F88FD7F02042DABE9F097F9D6A076B30D8CD777B1EC12BD163FDABA +5972EAA61E3C87E9AC007A052B1A3FFE14D7D43C7A0ADC89B1DD4CB4F9C762A84A6C0701494B2D8C +4E4E1A9245738BE4111805C2F153A20ED9FECF2DCF4C8F7C3BAF84D60454A7403D4F5F81C6404173 +A7BA81BB0CEAECFD493D877465DC5735D43E3102CEC57B8A589182FC65A4704661A9E351FCCBC731 +5A87E62F65D24EEB9CEE979C6E10DBCF5C162ADB926EC8CC9BFFE381F6B8A3AC0A19D1631BEA2938 +731AFC99E8EAA39BC75DDB3A39D01AD8F0BC1838F4D674B9BEE9F6F7BE4D9C8BD97E8D171EFF330C +15B76614A1FFD25B3BE19E4A201BCC850F926ED51616318C965AD2F0E56F9433B1247C6D5B72EDF3 +D408A3E0674A509BF30BE813A5E669D72B978794683CA8B85E3469EACB167C30F7666DB5E081B81E +E99ECFBC1704B9646B1A29E4A4CE5654CA8409ADD60145DFC54225BDB8485E39CC98CBC3F38FD0A7 +97E5DFC2099452A2418C6636BD2D5F6B24345ACFA65F4E7DBD2D0AA0C1776A4920B4466C509BB5BC +7D6627946C4DCB38A27098B7B5BEEDC2B3BA18F927077F71E38644597719652037621BB350BB5369 +DCCC073954026E6438FD8393DDB3630C4473F06D9FB9E422E435566C396B12FDCD5605DFEA232171 +CD8EF298786806E9159B84599C26D4C7D8C3BB064665CDD072E2083190372AA808B2268B3FEC8878 +B6420CA829BCF995DC20E067EE6B8E44D2869D51BA3AEDD1763F7F8D2CFB8EC41E6E9E0129DE5343 +1457960CC51D546B10B8B6CE08A1C2B79FBA448DF9783D815608A16C55E589DCD8EF6B04C66232F4 +7A473973A35618000D79B8173258B7365C9691DDFE47B16EEB08B28F881828B946FB5D6FE10ECC6A +FC4EA1F762E90B3320403382E42AF4885B183AA48DB5E4DFC9A54E0B4FFBF7C26EB17A4F13B4BB93 +12234434FFF05549E7587BA0373ACB3E31418BFAF400D8938FC6466B94273D1735306AB912AAB13E +31DA3541C1733E2A7E4DA5B82767D37F3084AA7A7C488CDCA7ABEF77D19E42B4448ABBD346E9BC28 +8ABC4540C0A1CFD0BF46C5BC7454B25E27E9906A3E6CBF678BFECAD1B19B4E42398A210CD567EC35 +FB115D5C0DF0EEECE593982056B0E1D14C292F70B3E049984F8881C8B477956AD3140B4AA22256DA +AC0D11C4126808B5B9F922BCC5F24A77FF352E2C621A3941AC07A20E550A69C49B1B87D116EE6F2F +970918F0F1A501166AC4423FC212E4EC8039AC7F9C212D864F418CBB92948FBD588228108FAC1AD1 +837070512305C110F0FC3FAFE6E1529C2BD0DDE868A9EBE5137DFDFC5C12A3D08014BF0EE27B1080 +02AAD6B607F5C5C0F1B1EED3C552919C9A2E97204A8127F97B1066607ECFB47BA95EF2B51F007C29 +3B2F6A63041A9C1120D9CFCD5357222E5B02DFC73CF94CF9B5CB00EAF073E9BF253E30E09B50341E +57BF245A746EA31BFFD0B00201C34CF0881BBD1006BC9BA7D420A48E53686B598BEDB3449924EBA5 +8D5DB1B1B01AE2BA281D5758C99EFE38ADCE18F7B182FBD0D0622A6EA497A4E7C00C7D17299A2765 +EFD8DE376C214D01A21819451FC04A0277EC84A151FF93903D61C78AB7886911E36E12526ED855AB +43F6289C1890222602B8EFBF15782B374AC1E580B6E963403D6D15A051DB8558F2E61C0B9476C6DE +5D4861585CF515CE951732F20D32969F39192FBF1690D242AC04D47E0C53D467D0FE4656B9526C0F +7F852348B0437737CB0F29ECF9B54A5E17185236DD0C16349C3496F3ABA569EA20E343F6D771210C +39DC932DC65ECEF94575C6E76902CDF6C8C8361F9C757A2577DA535187FD526699917CFE0AD438C2 +A758727B306BC7979547E68B94E87ED820614BDBC649D469EF6B4E4E3DD2EAEB5F80B22FE576CED2 +56495467C76A75F589460061E03F3A1B065121A5ABE3E2C51148B3DDC9F624C97889AAF7FB84B158 +C015EDA5670746C6359D27B0C2BD65144F2B88A64331816DA904572BE398E015A9924218B3EEF951 +23AABFC3AC8217B7B4F691219A1C9DD0A3EDD5C04E63ACBDE71B423522532561F4B71B7028415C34 +37E346BE728A415596AB749015C1D59BD8328E39A850CB98085B34B57FB52DD1D154F98FEC49B3AE +BFCB1672762E4D2A1ECF02787F59DF1EBF2625C3631BED849B298C6D226BE4E6EA2AB66A287D2BA9 +2A6C9C612A5F849B3CB3C25F17164BE286F6E4F5E7E4C9EB17BC68AA5EF0190B64696A570442E1D9 +BDD1A30E7692524E30E4B4C3DF84481DCEC6E10E7308E65DE9D90099F3FABB3F4F766BB86CC98594 +6D2003E21287761A7386CD8461615B570BDA015F5EFA23D18E83C325EE444EC166A1A32D9818C2A6 +5A092D44156C06D3FD079B92450B8A491CBB3529DDAC7D95AFE8EAF33777FBB265FEB8A4B9AFF2CE +CEFFF49AFBDCF6C4197497D3B448866D70EF28D8E4B17E7CE95F43F64BB48C4A73EB84B26650F62D +3E5199D64DB0B5B87702650ED0B850FD5D16C848D096E4C7E61BC63B2A3ECFC099CD713E12C91A65 +77A88D6F55D348617C7A49890A86EA8FE2045704B5ED529DB128C9B19EE129E5FE6498CC97087F6B +DE96007C9D01CE9CAF75646E5A5B32BFEAD9362A52223D746943A2D09C536CFAF78E601BC2D2F0B7 +63AD722E3A7AE7069D65F9F2BDED7278511D0120F5EA071D41A69F8C2A2D720D3B24B4BE61C83FFB +EFFAE21B0560A6FD1A44E53E42E0D10E0E93F421A8A7E167BB65F0D7F1DDE2809FA3CDFD931CCC69 +B119C83238C1C00EC100D8E7AB1C7FB02EDE97073C8A5860371A8132BE391EB1C397B61F93876FEB +438C288EF2E38DDCD182A5CFBBA994A94A1BF818312CD8234215FCCD7C240A15AC01A885E1179E5D +7D6305DC2F534BAA141F25EA6A5F356486E5FA0AE3C6980A9F5E8E99E7AE5B95AC42977510970245 +4FC951E4319AE4B1DDC9B07D0998372C0A95ABA6985A4DBE6DC633154FAA30ACE689D36A7F17011B +F29CEDC58A6692A8B3B0A5742E6CEC2F69B255BCEDA762DEE72F125EBA98891CFF4D88AAC14188A1 +8D81424979C9079E44890D94EE094D4CADDC1C7AC5F6791FAB8849CC0240A579ABD800EFE3AA4EE2 +F78119A3C2806C05C2B1F17940BE73984982D1C0065433A9BD658EA31AC819DA9A11B87475BB565C +C294B6F302FE3F7752ED9B963C5279B5F1196762D0E12E6DA46FF9A0CADE3876D7DF695D8965CB4B +47B351FA3F759811269376B2C3134403633FDE27C9B024F6BA81F3E1699CF64A426618428BA6C326 +6BF016C5DAA5FA4CC82FB6DC23FF2D742160518CD3A65ADB38E53F1067076CA1625466E0C64670A1 +564A54CE14DC5C57D24A12283FBCBFFD0FD594AC2A56EE58B552F7586825E4FB1EC23F8221711692 +C8C56F42272B87EBFF3865191F1C11943BB76D8C0CFC53ED452AE49404D2C8193ECC2A7BB8CFBF24 +870ABA38D2CCF7869E9363DC0AD94FACAED5922B324DC3B6FE83E7B34FE29ABC1EAD62B49FFBCB81 +1ADBB5148D5AC2743E3A058386036FADAB6FF071BC1C3B8023F908B6FF48DB0AB1C9C67487C35211 +D40995E1892C8B66AD6C9C6203F6F8B513B11117B10DA8725AB45B4437B5A88A96AF3178D856D601 +196E8162868A83DA64E408FDDEBD14D6591881EA652032CF2F88B3FD6C0479C8F89AC68D14D01AF0 +CEAFD95AD146E68FAE01A07F39E7A0C5E4FFA6D6A91D710827CA5ACFE7D1F946A8D7B67621D60F53 +41F32C12A6EFB03AE5AC5373A382C044A276F6B41C173D0AAAAE0C1DE4C3CC71EC2637225CCBFBD4 +5EAB92BF39357C57195B410F74283585B12B926438AC72AFADAAD2D0FA2CCA728C8E86BD3FE75D47 +B8BEB96AB13B5480F7A3D5741EB51E3E40C21FF2ED7D9221D9877C7D1A8CECF394E4023FCF8C4EFD +B38B839499FF5CD96A46AB4FDB46F35D3B48B91757C0159328120E93CF1F2739E936E28908FB1947 +1D3AD7F6F1AD2BD1EC364986A411CC1B547D0CA104FBC10B1CA7B638A60E75485574034561DB345D +DA68415146AAC632DFA34769B6ED7D7D4694E92CBFF4EFB16B55495908102E85E827FC623CF1BBE6 +A13CBF64E878E1A2A159948B5529B75E071744A5F0E50DF18C110B0AF117CE7F33F8C959D4C98CED +5A9D492AE6F56DA57B0F17495DACB130660BCEFB064FD8309D965ABE8D2BE98F6898C1B7A39CBBE3 +E75DA0FFEF6CC3945CE76DA3BE915546FE8A5310130AE0ACAA9AB73C7E041C00533B4BC7724657AA +649B9388B791AAC5EABFCDDDEA2CC67A0FD0AE9BE37DF9AD40636538EE55A83F60E9E026C64FBD8B +220CEB46E67410144A520FCEACA252E8165448F84D8EA083C793AD09B90B3EE83B73FEFC3365C729 +E3C738894B8C01C2F8AEE0CC8B114E1175EFB44CC4C6CEF5C8754B1CC7CEC200AD8BF1189D741CB7 +5BCA4E88BE959E32216AD33F674F49AB20A354CF3969F1611A95D3934E148831AE7C81A7EBE3C524 +4F743E66A82E10D16CC09F8194EA7A596BC5981D833318AB4F7DBF2ABCE543E410B649D18D146F01 +486159683DF61A3F880F9B21EBFAB77E908C6CFC79F89BA5F51114F0BF7C3CCEC7BF0F3B057C3195 +CFBA6908E31E0DF10DF69163C9DA7BABC00E9A580FA7FAC202910615BD479BBF76FB8068630D1EC2 +1CD2926D351E869E16C2CF1E023CF04D4FC61607DAEFEEEDFF5593E6023492F00029E2AE4B4A2C14 +50954EFA2792F32B4934A768F892171245A1E2F034E2B9F39833F1B331A19A386BAACFEC8C929BA6 +B67CD8922BBC9DC005EC3976575D5B0508D0717C6BF11123EA36D8FD37FA77A6F1F5AA84D4AD8D25 +B2C11D1877A6E2F9B74F3B5829FAEFD4F7209CE9785AA6FDE68672554A6F29D8BF03FE108ED90A7F +58690FAC399A8AD3A26899072B832874DDB629581A51B3325CD9EDFD49E890EA8959DB937DAB83C7 +77F2A426B967AF5888C33A3635B78D647AD6BA441E222C958EA58D61945F781D7EF409771B89B202 +42AD7D07C2EF592CBF413C5FC89EC30FC9EBEE4BC63709AE33B65EE3091CECBE610B847E12C556A2 +79C8B114C3E460822D3330ADFD72BD69F54C08A81848C2002A08326CF3B09B1305490D35AEE59179 +08E1604ECE75BBE811A715AE8AF7EA9C371B322D0428EDF4C893FDEA607E70E1B6F6614947326101 +EAEF18E29BE0557D2A92CF1FC1505E8B434BC368CE07CCAABC0774F8A63E1073FBBCEB3F4052462A +A9008A1E53F188C9EAE339FABA74AFD6D60F47282CD9FF721F64BD51787F3C13B5A6C5A5F7861171 +0111F5E0471E206D72520F1DFA465F4A23C71DCF99A04CEEF11B0E3BDFC35B7461A60753D3AC26DC +50A5956C9195A4F5226388E0953DDD03AF128A98F03BDFA0602CBBAA20AB9ECCDF7255962A332E16 +D4380762E498FDA4885C64FF5F9B480DA487C58E78943DF62616E6E2C69EEC8836DFCFA9EBF58938 +A878F3E792E8BD8C5D6DF557A5D82018DBAE1CA9C64BA5AF8E21BE1B6680FC5DB22422220B776E9B +A0BF1ED2B7212F8BF111EC8C8C77B223C05EB5E5F1CFABD2D037F4BA0F9503E2CD83F4519D180476 +63F09E308883F5DA5228F83045FF41214D2273B2FE0A9017D5E0557BC2A198C35D1E7E81F7965444 +5760CBA1D3F05EA4B90658E53FDF0823BDB1501ED51DA75C47395073D8980D1E3504E3F67DB3259E +4EE73A87CFD96F84E221796573958D364A51E635FC55478C9CBF9AEA16B7D8C25F2115CFE4B7F598 +54E24968833BA0D64D1D332A666DFA2A3FD71B05A26BAB7DA382907B13DE0B80871DF184D3622B62 +3D7E09BC32A4F6EA2E6DA450A906EAD36D53FDEC7F83E101FEF32F4FAEC581B000686D86A0D3861C +1E67F18A4C4647F51F978484D9E3100B37BE9D20AE84C085461C1FBF929C669E936659050C2627AC +1B019837BAA75757F5B0A82E8AE9CF2111931A38BFC94744E2FDE3F8710342AC615286E4ACE7F269 +743AA05463AF537D9416230ECCA859D8C99B7C6E70BE7FE11DB698589BE9E11900C8E9582A4EF5EA +94B5F62820C90DBC022A620EC536E06CB8BE7526A789996D0E741AAD980880A33800A6FE92286CCD +02C9CB407EB31FB95D9C9F4AFF38B37087AC582C1F7B64A7C3D2202BDD62E9AEB31BCA85C4CF323F +03DA9D318B91F78FDC0D266630F7444ED068B55C05461C97552366A82C2E743CEC353D51028FDCF5 +403B3B74D379B82EB69C4380ED40239E15A86B2E5C860891E26781CC111FB5705E3B7C7AF1946006 +54B5FA1B5FC54FD0BA43666E7BABD2C91C859F393ED49F7123EDFB648A3D6152F2C17F7E438C0A63 +8968AC06B4FB3F77F64F358AE063820BD33F0213C85C40E4D97ED100EC2DA1C2E1EA258BF107AF67 +5A9D995F60BFA37222B9C2B325C0052BB8537D2B27DD43A129C7E8FF42757B3AC9B447703D382108 +DA520B8B3BB3E8C7295B776B44ED28F863B8E1F81B0BD1DAEE8A171525D09D2620C04DD3219D880C +2ECC79282DD7B1772A9CBBCA706909AE8BC7798E6EC7375189B6CFCE8A875849176E5913B85A18FB +197A33CA4B5B4058603CF1FA79A56856B43D538E9ECE117D99AFA73B57E307364F553644DE01EDB4 +6234EFAC13046B6E047ECC8F63942F20097AD7ACF0A45C0501A95263DE9439A880D6B5C5214D2918 +0A54D7FE9B2E627EF49E189B59FCC78745E878E45B46C0A648955D3EA8C935113D94F92EC963F66C +F3CF3A526BA71CDF3CD4CA69EFAB08B7389E3390716892A4872BD29DC1E0889A42D7FFB4190E9A8D +05D84EB9C5741BE6B02716BC75E0106F5F94BD3778BE985E03860D27E44088C3CB2A059DEBC420DC +E3A8F4087A9548485E616C409AC400DD1C411CE4B6A229D091B253EB68F06E43511EC5AA6ECA4D6E +4818D6AA2068DA1AEFCA377611BFA816B5215182432D5683294D67A7C1FD76C52233087CA44943EC +7280005E93145F5E7AE50100C18364E1B36741E9647C4DC1F68A58EC44095920FDCF05532F603717 +80F78420077EF5C24D63E26040CDDFF8DFD65D871DB943F50CDE84900C1372EF33FD8AB9889C82F9 +4F61A0E6842219A0F39EC7B232CBF802C4A744F33159432E827006C7CA77E480A48A9B0E6A876158 +8A3102E3F98A77BBD62A3A23150FD140D3941773BF7CBBA2338FF37B9EB640558A2313E8824E8E62 +0331568A9B76F4897198A709F9313F4AC40827D8C3A71F2ABFF02BFD57D30D0B14012FB5C39B85AF +540DDA0ADC27A85B31694E8D7B61F9D9B476571022D98F2D768246550A877293F3FF6ED918A498D6 +A600223E1A61890C49ACFB60265867CE9464F9C32C59E94F7641C3873FB4FA6EB237F8ED94579957 +270D6FD640BD9543E683F2372CCD7B60AAD269E03A72C5CDB732B128818D41A6DDD2BC139F7D3911 +F48E1B1D263DD4AE8E4CE1A686F3A00A2CBF48978631CD243566E22E68F8D7397134A3530EA3745E +4F1EACB4D6A5FD84C3011094F37573F7F9902305020C53926716D4780C6B0A257BF711AD94C83F1D +41A02C1C7DD203A3E6E4B14EDA2FDBB36B063A3E074495F626B0EEA146D22AC33457F44F41675967 +6D2A0566EC2B726D2F0540ABF225339F02F406D4E7A62E5233DDF20AE7C86CA0CDD561F33C422654 +BF2DC3685CA91BB9D4B09AC8B15A24A99FF56E2894F11F7BB4728FE8F0F5B799F74F475D2D01F61B +7E9E0E541F7FEB8A557486D7DF2CE50927515D833BCAA1CD9BF7A650BEE9E003A5951C98ED147C4C +52F64F692AB281984EE65A47E44A4A5FA93D6F18D276D3B01C5E5F6135AC6940524CD713DF4077FB +4943E8AC927A68489EA52ACF7A854393CD027EB52EA2DC6234EF034F3DC742D6DB5A67FC21D22B97 +146B9C268BA97C30161CE01EDC69A6A1F05EFB0E06F22644E1A368F0E2C0C6C1C832878E0614B74B +D645F5CB293CFDB7618B837FFF14A1210AA061C8C81867244305B80DAA73CB25A417228E9559E7BD +52C119B0CCDB7C4DCE7E1B9F7E8EBBCB575E5BD213BDD6DB88769DACB05E5870232F0EF82F448559 +187423409EEF756BA6247493BE24CB1879B5DD822E03D0ADEA1EDBDD83D3FC46759C679B921F0616 +F27212903F728AB44C1784E8A7DCED0DF5625A7D3F48A20FCA34008184CECD145CCD98E31B79E174 +CF107E8F35C40C19D86B40BAEE6164353408801EDF75A619FFC5B6FAF3F3A95F64795CC40C1F8963 +4FD8C13852D265FBCEF834C800AB46E3E8167476B23CDD8AFF6E2F997C99A86A9CB30EF8C853154D +0D89EEE9B9CDC1B4F27BDA32432A4173B55CA8D9FB50ACB2D886AD8E5862FFD5DFF224BA13C8B8A5 +4A7F1A9F987FBBDBC5A3C3D762A5BE309D5D926AE5093C40AA47B3B1BD828797CBB9BC9FEC9D19EE +A73D2A39764816113A8EDC6CFA6E605AD578FC8E30ABD600658A49ABCD5AC54655D29C50FDB72070 +169D1B389F114B7C71EF95A80D82AB537AC8C165D47371FC142A51625029A990A577EB1618480D72 +6DA93C98E5C5F24F622A850CDD94BADAEA91D4BC32CD50CE69E9F00E77DEA8EC1D37916398FB7092 +402605359DF08AFE7B99C76C2A7C70383F28A7C000C696F45291BB8F074791798197CAFF1544C76C +EEA8C9E6D76EDCBD92A86DF889481F3BBFF0865442264F0EA40D3CAA69AE467A08003F9C30FF7F2B +77E767580575398462D5B1171DD441D8986F33BC7BDA17D413EBB6B7A32642E33F20B284BF3EDED0 +02352FC66C6F7741A542155F4A159CD778BE56B9492CD95115C1A06189A216CFD2E6725965A13DE9 +73765A05114D9A5A4BE0615AF8BF6A5EAFF84468B849954D15BEAE1CDD57C435788B331905C01421 +B50F20B184506A0BEF746330BC98E9C89AAA8F9D102F158043BEB6A682059A1C8B8CF67B2F3D7AF4 +D8BBE086254CDE53765E3226BA2F95AE8063649F9F94BD9519411DAF8A0287307335668190638806 +E29484A4FFBC1E46B1800E03B162C23B1DC0B4C0DD3C7ABED2F00762972EF06EEB9BCDC7B3F39C70 +BE32789D366F073AC3280C273DFF2979507671B3E1E7685A9A4F0FD3867F96DD675BF05F25ED986A +79249B75F182FD73CDA2A6A66D693E4CC5AFE3402431B2C816DA1486C34BC9DCA4E2D51C868688A7 +787CD10ABB9ACA14B7181369DE89913CD8FAB58FC84519EA2AA14E54B7A8CE474F213E07CF2DE2E8 +88093DEEC937526816B71C96ED75FA9E2EDC0F9E6E84569C12BB8E39AAEDBF546630745553D6084F +F9524FEC6A7264F88CEB7EC3358E923B392474E3A48865564431662988FEA768CE555AB0DA48BD52 +6A84B0CB17B4584066C1640C1023D91F7869EF0C4D701BE121A6E3C832010427490758AED7A2B30D +6028F2215AA44E86D852FDC67DA5CCBA79EEA863BAC9EDC2535B66AB0E54EC4D4411390FDEB8D1FB +C1743F15C3B68DC92A8659E7A892D5E53872EA51EE8CA7EF51103E87C29A2714E907C79DB9CF3744 +1785D2F73A1EE58550111A4D9BCCBEBF2E39CD3B93DCA300FAC3ED1ADD8215301E5766C30C8CF296 +75746C5A77BF1FE3CD75D25CF193DE8D9AF02AF8F7A6E8F84B548058CDD3C6998ED13463FADE7391 +26D83D3CE2C7201F955382832E32C10DCBCCA35835985B9A93F8E3B0208BE6E92428787C47D3808A +0F77B8F1D76E6BF6A17FF81CDB065180E03809D03638307BD7BF5CEDBF64904E918FC805AC905379 +928B816480F6E3BDEE47042CBA98539DA0E113B1A5F23EAF1A3210BD18561985E6436EAB90395DA4 +77C7A6D7888D2377B3FC4169368357D880CE041E1F7C875E956600DB7D9B35D1EE66BE476E9DD806 +4CC02230276829C2C0A098F051502E828A0CC505AFD8C3DF293DA1508AC4D25866BEEE6BBD5A230E +9C2DCDD4F06883936381F476DDCD86CCFE15C2CE3C3243E148CBE603B8513A7CE7A6910A66A90B70 +89E5CCD4368BEFFF2BCF8E918BFE0A1B069AB2A914CA7BB91A0AC3B3C0B060FA1A0316F6135E890E +E549315897C8464496CC6DEA0F7E3AF43FFA4C3281156067582CA255B1D2E80F999A3AC0402BBD17 +01824C3BB524130F5B82A45275807BC2F3A0655EA208F968B297F98C369192C8ACA26BEBA7DC4506 +FBD1305E2EFA4DBE5375281A88EE2D6FC88FC0A755E72934B4B58F6DD3BDAF7171A4A3C776576735 +2492BFA9A7758504750AB7F38754683B70E9E293CB1CD7B23BA62BD7397ABB84D7EDB22EF6C3F58B +3EEAF656E361747ED04020163253D1CF3F905B5E85F83FFF30AB2778CAE43781667C0F65C8FD404D +6B9202A99EA76AF9AE1236631550B66B063847180B6DCA832EA8DC4A6EFDB674B5A26552A7C7D54C +2799C7D4E03C24F661A91103086DE3A90A774A6988347656344CFBA06065AB22476BB09FB68F9928 +C0045F2764AF643CFEF0516D87FDE6DBF93BAE2829B176CB507BB99835E01BAD5E55C2F8798C93FA +35EB3FEF02CFA31D3D21B030547F86D27B9448D68E2B155A65C742BD2999DAA0C3AED64447B9CC67 +F7AF33B63AFAF25F3CF7EF86657FE8F952288CA4B691D369E8F1935CDA44A180A6767560C2ED3F2F +CC38B6BD7991D4170C7C566D690A8A25BE03212A80871108D18CCEFF246623E653107631F29227D6 +4754B2208D19F84E547799E691CA473780DDD56AE620CD953D5133D135E3D51F237078FEEBB73714 +54EE633CFE238AEA63F9999E32850E6C197687A0EC4E5908D2A18C5349627E336AB5E3185B218228 +603A4B1852069F5EE849D571B8387DCE1F8F8E9FE94FADEF128BA83BDD245F8C1C27C11F2ED1A8AB +2D6D601726842CEE744EE7AAC6B6FA16CCAA39DBF5B3B1D47339F31DFA562671A9CF7DDE6915FEF9 +F19B3E068A464DD350A3AD146D1A241673B5112A4A8768F976723E6E184790C0604506C46591BEF2 +106C40789B733331A80740D59ABED39868F80BECC2AA21C400A0BD0CC326D186FFF9EB37680F1EDC +32AC78F9059280D07B5FF2E354FED545129FA5FA8F3D4317FF21E027602FDB2522F049BB545FF4DA +60248130F81F4E348373142F3148DED038AFBA818F26D5B49FC02DE9800D894E9239C88EE0EDE431 +F8083697CB0BE3B497473473E5714717C914A1A926730C249413FEA2615EF72BDB0906933387A892 +370F77EEBF62D26CD583EE643B02E323821379C0DC966407D36AE3CDF646B95DEDC7D7FD0F28E950 +78F12DFC0D6400B327B743C548A0A3517A175A7ED963ED756B1E107AE7087E2446BA702CD4E26E2D +CDC1A8B697108B5B5E81E9F03105F220C72D4AEBC57665887C8C7964089FBE9424120EFDB14D76EE +F8C6F7A30B13E1AE90CB9D93D2E14BDE47F4A1D05ED5B18D32AA39911B92D24C93976ACEB7EF597A +75161923A73B2CC761785493D0EEDC08B5AFE95F3C006B41438A0785C962B070DE2BD096CB63B847 +C87539880AA3D3FC5C345E0992D7BE77C6CFF4948617FDDA784CC55652192B0ED775129C4EA4245A +41BCF3875BE319DA0EE2DAFEFAE920CD2B6C6C2001762F88C0C5C05053025C0349DB17104360FCE1 +5D7F3A8E30ED13155A74FAF91DC77B8AABDD6FBD5A1EAF255DB209D7F2B90822296B5603FB5E2CC9 +5CBC5F7A6044058B8044ADCE73ACFD896177F1F70EAD2F6534DC3AD755AB2BA87126D63CA2E9C441 +DF0965BDDD6BE494E58D6B5057A561D1E31BD38E92CB73C1465AF6B9C001F7229059BCA4104847D1 +639E124E082F7364B56548BF8112D0EB461B316B2449049F6A476D36D6B7C0C1126C08F2E9A1246A +3B5B21E7C8FAC6E23B82E33A7783E4F31F0240E96E69C9444E7D7A928636CFD086475DF1E0A28464 +81387BB2010655B9F81A0744121699B4905AAEDCC84BC5D5AB3674601DBBB651EDE7B5DF05C8A463 +DAB41F79706D285C4F9063997F7AC8CEF35CAD51FBE5F5BB1B3FA6DA2C3ABF2B3E925581349728D6 +DA0D59C1EF6444539742EE9A23A5727F20CF9377F4F84DEA420607015A30FB14632D084A2DD181BB +02FC3A84FC499B318156B675B9CA3CCABD87FDB2497C6705FA70EBA43ADDB6CF961B30E8F6AB9F84 +E1DD8D6DB3314B34B7F7AA3BBE19D5BDC75ECADFD8EAE19E07B387A1FC586F0F30DB695926764B54 +0D89F1D854B0FF86528AD9523CAF56371E29498C11AFB2F4D5202670C834E930103F039D13348824 +16A49BF93B84FD3CF1209EEF7D4994C8302436C0794497461C11F5B8BA152BACBCC08AF8A15F4A4D +F3EFFB7227CA97FC21D2D0356C93390C749CBE9750B821F1A7BCFAE2C8BC6D9A27F844D8AD088320 +79ABF0EAD8ECD4EA72846DFEED021857F33C1ACE4C07BEC90398B629814C498D33BEB375B9A53DA0 +F926FE6E89E70322C72CB2DDBFB16B13EF7A4F50DF783316584C6AC2BD7D9029124933133B2229BF +74A228868AB30EA5C3E87C78C3F0962199480DBCADBEF53BDDE45849DA857A4FD85B96682F1EDEB8 +5384929DEE4AFAF84C51A09F5D572705673D885070303FDB47DC898F874E103A9E7C1E894115DFDD +AD81549C7375D4AEDCCE2E52C13E5130B47F206F7C5AFAF1F9EE83DA8188D70B473269CA280A6A02 +DE85300B93D8A4F6B402FB5DF58F1327470CE11CC63ECEF2EFAA396A6680A6746A20382D9529B58E +7CE684B39AC00F7086BCB47C2230DF0343BED9B9152A61C9826AEF9E00A1452D91305CF05490D4BC +0BADC9C6FCBFA93FAD52C3A80705A1956890497557C0873EBDCF61CCDD2219354A4F5621AB33B119 +32065C1D990A9B68858331EE7875CAC855F98563B14EF9E1060BEA90F195AFFF94728AE935453438 +DAB35123D0E2699475884DDAFC7307A5CC06920F35341728D85965F5BA86F261CFFCB1E29B429F97 +6970D42D10E6AF6C4B792B4384122AEF2448E22A58D3AA007743C71324EA08D06819FED14AC1F22A +4F0BE4787BC8738E1CEF240677571C65804ED3E748D72E89C94B6F310BE748FAEA31EE246859CAF7 +A1EA17CCB5B246C87EAB771E2AC5D378650191081514DDC2C66878E3766CB20DC49F630F2743A7FA +ECBE9DBE9E815A3CB57DADF2BFF5EF2FCE23A56298A30A2E052FEAEFBD698101F9DB992613706693 +CB0EFAF6F60C8BB5E7D0A50B3392B9831EF3A304A846CD4AF431E9F018FCD3A5B16387552D55DAEA +683D36257418AAA0E7BF8A03ED7BAB114D7C15119E6C71C1946BD7903C1C42E115E954619051B853 +BF05AE316E15E619A7DEE498F771E809D9435969C1056402725EF40C0200E083F3EC6E0EC27B8ED3 +8DFE32EA0E5E156AC36C4BB9AC5ED111A11678339703F1B9299345AEB1F251FCEFA11FB3101CC499 +907DC862B4463D5523B9B25C5B69F70AB6B29CFC1DF1ECAB8227EB3ED1F882E90B12080EE003714D +403EC43B7B54491446B6A3DD6EB641EFBFEF060C45E873E7398025B1CB7065441F1753028F6F8C49 +A96801C0D598E098EADC96A21117F817B6FD6E6947642F93E22425A00E8F6B592AD50B317B69C0F9 +4047386A45E5EBC9504FE55451A01EB29DDF9A41D4BAD85FC84CE280971E834F06CEF49C8C20ED2C +EAC889F158CB14A8C070900478804CFF1D1637CC880C81AA287D8382837FFA8F41FF3C9DF2F22CB2 +0044C171E4815D0D0F6C22D19A52114E780CECD71DAF63427782E85E463DCB333789F496340E8CFF +885A9D9A4250118B439C71C6BE51A9338BE29251AA794EDC67DEEC6337FA63CA9B03C1C9F75E733A +4A918646E7BC9792486CB5A4BCC5F84FBABDFE338C3792254A3EEA3D88903C2C47B91E076259DCCC +8BD3DCA90ECCC832C09C45141C6242026BFE309029A562C3EE0FCCDCD40E5CF265ED9C3DE582884E +0E14819DB98B3AF734B1B3276AC41D43384EBE73003D15CE39FFCC04109583390E470F431B4407F9 +8550E138F96C4564B494E5480F47C853BDD237E27301F55E42A3BED18FADA152572B7B465A581DBF +E7DB2619365CF16D71BF8F091862B9FCF04BF8D0859A76F46E7B5712F2757EDCE332D3213B8A30AC +2CE7D7797EEF6F30904906B0805DFA7CA36D32A20D989858497A66CE72491393DD79332003D55C09 +5A5AB5DF761C4BE5C041FA8407263D604E53091F7B6B15496245DBBEE96A63F10FC2978D99E65731 +28689366FE8B0BADA48B50185B861BAD03E3600F22BAD4274F2542B635F6C7944BEFC3BC741BDEF1 +1A8DD659038CB40FEF2E16AD1AE7EBEDB7D9BA15FDCF26355331505A386DD7399FB999535D6061EA +BC61DD76EF3EB457446F29D0BB6EC2FC0AABAC20B27A3C123C27BC27A76336D0A0A6D456DA070367 +4D959A4AFE428E2206A511BFC80039ECD56E75F69786DA0A8084D81A66644DD98B6018681F1D70AD +E09BD9BF3D16D68DD5D0A03AE26DCF1552549E459FE190B310A8776B2C8468C14CA8B1B9A7AF2956 +507A3B705AD75A17A0EEA7FE089273353CECD07BB8563465EC8DECA0EB42F43FE3664EB5F31E1D13 +24185539B28D508BCD065ED576D8814ED3FD637D576F027927162344AFB0255A91FFC616948E4E35 +8867E9FC76A9AFFACAEBFFE110808C1532A2BBB0DBEF3F010E45FFC73F228D28F12E98478B27397D +8F456781ED9E19711DF2E9EECBC3FE61F7493FDF1A59124668A91BE51F122F93DCA4BBD22DEEA339 +E6EDA3D6EBEE03DF958113E1CA49C8398D2C59DA6764882EE3663F62A55AE50A7E91B4FEAD1B11FE +0D50ACCC5D75F1A515F0C53616A500F1491381DFD0E2477E402AB0CF9F67D501A442629C8593ED5D +25A72EDB9746B02F2B0F0759CC9CDCB4C9D8B4519C8C617E569B432F0CF6890372AA879CA7DE46E1 +10D95E230A4F0E52CF65811C54365DF4A3E40D819E2FD379B47DA3233D0DEF0EFBCE04AD8BAA3888 +4F6A69FE5C373E38AE0FD0241480F2BE7CCD18AF85916D2703A049779FE7398FC47D348454CF03F2 +2EB3FECC064606957898B5643464845445C25C0C7D685C8DB042AF5D5882174374ACE90081C68678 +9BCA96AC602EB41D317BD652293EE628951875641661EC86A2C40A42E8F0813A861D41A0F5178E55 +43651CA0E99150462DB5EE0010F00DE6D55B0D7FD7EC5BAEA24ED3E90A7D6A0589761922B91A6A91 +3A7FEDDD3B68254D89ECF767CE8E27F966426A8B4FB1B4085384FD09D63E288405B78A646F44C87E +EE22C8596B13188085479F75F63D3D97A28F9C8306FD207DBFD38DEDF0FFEB7DD80B2A3292DFBF1E +D605ADF1B33E85B010309E3EC058FCD922B1325FEE71EFF2DBBC2E68DB52D513E024C01D47CF657B +B61C9734649A4AB63C0AF4720EC3EFCD82DD3CA6E80BB63BCF1B8DE810A0C6C517C63B76FE68C0B2 +86867BE102424FC31C4937048B6F323D039618586FC21731005D949E7D802A430DF8D2F0CE99F2A2 +376C2953EFC4184355E4D12F422C9E1E25C4DF38DEA334DBC89B540E14C61A7769D77115CE8968FB +76B27D0863CEA2496783114C24D4CC816DA884D953DA3F9B9D3AF8938BC607BF26A071956CA07E6A +5509EA2F5D80E5CBEB98041B197FAC760976EE75B470DC20AA023BA3F63C2876EB281FF5173BB490 +D6815604517AA1B1FA0631401B3C1A04CA103E2CA4ECCD83874D9CFC8ABC134CC0F9141D9AFA5684 +8BF222342016C556C14B3482482DCE5D0B6EF1AB522AA1812BDD8DD3397E05327EC12748FC480842 +9B97202E24E1DE0C7C0D272C046BA73B37D30930C5DE5A47D96955CB0F5DED8F3AD929A8B42D2839 +0458F5910A0F93610F79EDDB27078943DFE17C716D65F96589769349F3B66AB7B8C004CCC59EF688 +1F745EC7129865A76F9C2D029D4660CCFB4D5F9D412BA3372A27CB175E9D65F759575CF14A5899A8 +D31FF039AC02DBD8391C3397428AC0D5717C005200790785354813C8859BE90E0E17914F6CB9C674 +F1E9A9648657B54E5E1F52756C4F982DF74E73F6E4D40718C71D1D0E2420FB7462FEC9E457C0414A +96E475C6BE2C10437096FCA0C942E995A9ADA789AB637B648781D32DFB68E62E91C2CE7E13680F8D +31ECF8C824885FA7618981CD05FB335AA111B409C59EE337DF4E5F9DCC920A5FC0D620DC07F20DAD +63F4FF5E0EE5A2F390AF1C32122BA7780F210229E5A5E3ED97BC1C3CDDDD456E739CA782EDBF4B81 +0552368E9C734B0C78B0B8E3F8B2DD782862B74318871BB1EF087828CC173D7B049811FCF598B8EF +DE4D9BC5447F4848C98029C854F3AE461B9D46DDAD8CE67A521F3C811A81A396CB0F80F3C8D8EC88 +30532FB7F9624F7CAE0F8C6DF875073333DEB28AAA90AAF486AB8C932553CE697B885E71EC8E40C7 +835CD5D59A2C695DB9E51216FF9B77A15B0DA63717FF25B05B939E45CF7FBE490E51E9344213B32E +115C2DE14D76DFD5845088DE645B0E75042A61D82FB1753C445AD0A956A1263E5A096B681D3BC51A +9FF32EBAFFF7ECA8B59D40F0937EEFF38312AE57462C7BF3B1FE24D2BA8DFE84515270E09063CE3C +80DF4935E409F62EB4F54AF16A186D4329972B9BDF15FB08461B688ED49928429226CAD9F67C9D63 +6D1375CBB7B08A5631956B7FE29CC9EFA8D75C9E4919C8C2C54F401D2E0D7BFBA40C50CAE214D210 +C6F3EA5802339F63FC4C1C1995787617F3EC2C806CE44CF8E29F76606CD5836F6E5A2E423CD791BE +CD3F112F25657DFED9366FC4ADF90B685CCE4A5698E5FE16D7542B913FBC01B288DD13F43DB2B1ED +8CCB80159DBDC90A8132125DF8DF547C4851CA609D1F6F4D647741260E845B457937787827A89E37 +CDA06BB191669AC84B8608EAE132D10177F3FC384980F3A6E439B048A38D0D6B9CEF09F3F2D732AA +71BD058169D6D0F8C9D146D9DA046774027559A8B3843F6116B418427E78476AD8F0F81E8A6B1209 +8060FF7DD686503F972D6C42FD6CC29C083AC3D72E3751F21D2E44A572EEC80E81EE44C90FAA7AFA +BCD3ECEB98FD4068F6C3A4DED0E6CEC523C9A0054D1FC2A8D61A4A26F9BC250B8F302416924AB22E +722297888B85B9C12F8DFD2A744CBD143F9B2514C1CBE988D9CB4E77D90B2EFD5C2A528355A35F7C +4AF039C7D1D756305967B847D4ACBB81263D4992C001E2A262B9FEE2D1F5022BE5B15E1D8F1D67BC +52227344EE912C018CB73E5F47CED54FD202627777BB77AACF3EE6B22706FB2FA9062BEE87E22CD2 +802E7706322648DAA0C624EA885430175F746E1F536F9A8E1C610C4A761D07248426DB63C9319A88 +A3FA449C3FB8AC94C6003C745E6BAD717A3B2EA3862D1E08512A98E57772A62F85F1E2FFBA40E2EE +43AEC11203DA9CE5AFBF673436F2DB6AF85BBE89D802F7A9E5FA25A408DB69E51F0577DD26F94CF2 +BA2FC53EDDD6FBEB534AF15F74F66EF8D14E7FF77D8A5D284C8202DD5A6053CEAA606BF925992382 +5EF4EFFAA8D878652A4CAF2EE43ED26BF3590402686C876F86C1AE95046E527617CDD3C429BD4CC3 +F9654D2C76DD4102471FF746FA9FA379B16DF96BFE3836D43FCC0B8E95120C27370049ACA4AC313E +1D50D72D1814F2566B8B29FA9C9C20D0488743722A766436776783B939171FFFA00E04805A8B5821 +4D4F114F7B9C3C17CE7486AEA2BCC895ECDE809502BDE57981318A93F23016F056A421B733C4590E +34AB08BB348DA4A48F19B6BEFAA1DDD2A49A6C440443028333CDD48C85CD698ADAF3FD8676739E44 +400A98B575BE02350576F96CFA54D4184BA47555B8D12374B86D038D085F7FA51FF4BE2FF5981408 +999B48B2FAF305212ED54B2E371F5A0074CF68D1B0E5CD279BBC8BBAEF694A89A6C43F518D01BB4E +8402AADF34E96E9B3FCCAB4CBEA2741D3FD9ADF7AF32388F7771845AF99965A6078F4DA335EFA436 +BE36903E33A743C112C0267309F266DD44FA998C9A139704E400B89DAB952EECFE2AC09C82D9F497 +5371CCC27DA37890EC84123193314D8A7A707C217FFC951A547EE5B6D1B7C8ED85BEBD9D3F4B9B09 +6A78E5F7DF88C931E3F396973974454E59340CA51DBFEA1A00DE084B64630E26C6D6A3593B828814 +E27DB0186BF2A87EEF268AA1B135AC09B52CFE53051CBCC88CEC5657BD47F603C8E1A6249161684F +D9084AC279F57A4F9BBD0A546A87E147B62AC860911969A29B8AA20E3AAAD0079D64E6BF1B0F2CE8 +F0C54C9019207E1B403358253C2FA93A662F63B9380B65C5173C198D86A3D0DC1800D1F5378DA39C +E8523EB62C6AFAD8A0D7AD1629F2CECAD82B8FDE38975303768C7D3A08B91478EDB3C45A8C6B7725 +EA8596A8ED50B8355FB852FB8966479D12E1086223B1E6523A65FBA81DD106FE254F7309718768AB +009FF7714A8C363B09DDA73CD3F81BF9C0CD3B0C806CF3B7BBFAB73E46FACAD2480EEBA97AE68EC9 +4D3D79AA01ECC22067858EFFA9D7B7F997ABD2CE5AAA8781E5499E8580C405681CC63EEA53BB47E5 +5ECC5BA2A7A3C5472DF034B022F455C60FFF971B01583A29E211A87F7163187B190B0C1083D696B5 +86E9438FD8BAA45101A5EDCD1BE5AB9A585511089DDAC8DF1B1FDBE582ABD945E67F99ADC4452988 +A9859E39C90EF794C5C4E62997085B7A16A0D90107D08610BA175AD66377345662DA7DA4D8FEF847 +EE5D57E3AC54B928A0957CC1C944E7FF14658FE4A641CD26C61105C0F136A75950764B69CA17509E +3C19351D456B22C87C55E8DCC4ACD3E150D936333FF36499AD6B02B6403DE0F12901301ECB2EBA10 +324BA72B58206A13B8F37B0AEB12115D0C12879C8EA8A2EB70E85C95434564BA3DFF481C8972587E +FF74EEBBBAB14FB32B8A84B8FC42EBECA65D25E8C32C19CA5962832BF45DFDA4E871508AEC318495 +0D6DBE89019CEA29E40484C36E33D76B756255531ADD1DB24C03B2A64A47BD8FBA3FDCB1F5B96F8E +ECB60D5834AB001A70740498720AFB6EC03445CC35B51F7987109618C6C78CBE3041BEDC69B6FB12 +8142CEC5C8683B558AFE3024EFF7A12D04EF59A72E156DF11D33ABA08A8EEB16259DD9529CD003AD +4EF4137B6FF1654236473DFB93F597331A5E26C7796F528F65C94FE07B3B4F4DD49034FA0CC189DF +CDFF70C2F1C6D3DF30AE103E2AC5CFF20664AB934CE5C19693292071C93BD590383E0A1931E04D1D +DD18071DAFB628F5D7472E457BF81D6064EDFA8DEBFF91701C5038CB30865D6122076A336732DBCD +B0A625548773D0013648A76F07BBDC9C16284D158EC7A105AE37A62279419C3A2F360D0C7A74D6FD +D0E36DCA2A8BD59945A4196598F690878F84C894852C1811AFEA4BE3B9F6A5219E6628C66669DBD8 +FA9A0CFC2DDE7716A356FC4FB271D8A2CDDC8D4684DE447355BC7A287DC56852A638C5777826EB6E +B72FACCC86F80BEDDD0D649A883CFEEF4D74750172A90B5DD8252592FCFE19FFAAD868E99562DAEA +E70514F5DE296EF7B57E6F193737ABB6AA317956584423817E11664A67389197AD9F8F771EA59551 +98C9EE40A0761639E638CE9D890DF468642670235F1373D3AC6B1F43B5777FC0A91A96E095E89BB9 +FD62614DE456CE7AFD6B855112367573FD9FCBBD4A4F9C676E672D62DDD34A9BFE8311B6175A003C +D143C0DF15E4C0B48C735404086E48AEED6B6FA21FD9F40B84215DFF287F0677904E2DDFDA774A40 +19DF45CC877F553E95A1C65DF1D67BC0C60E0BBA4D205C0DA3DA80229FDD71859F65AD04506B308C +2B783839F31CFE4425263224F08C5C7E98A2C9D3DC8EA5AC1920F4E395413262E0836BC019A092A0 +DECA104EB2DF6B63392AE8E2136379140DE5FC98B0B69860FE8E31DAB5C5DF7807D19BEA34AC14E0 +ABC6F6519C51247B104DE7D912C5BF6EF11B48FC6DF84512E9F5FEBB48F72FF1B722BDC3BB2E835B +2E7CC6324BEE84893996B8DC2D4DC2793A4F69C18E63DAF04A7BB5C0A9076E2D5A343E134CC3C89C +4712900656FFC202E1988526D80C7FD9281FE47FBA8AB5D025E63A84051F6B13167BEC15B346212C +BD051AFE7A98BE3A2491F3C469718A58E783ED91F90E274FB4978F8719E92A99A1E8F142EA7E1F2C +46AFF0A2FB50F4D105130CE8EA309B0E480DC8F80D506172B609EA4BB4E2BBAE98D8882814FB273E +690DA990B60A9CDA20A2418246BD10AE67D846A0FA815AC25858145ADDA106A6778A11877FE59A2A +BE300D7DB9BBAB31CB5B960B7E4EF91D4600886D8795DC361CBDDDDE05EBD54B1941F426F7FA8399 +270D2F54C998BE92D146227270A8E89AF90C48BAFC4ECCCA01E6322AFC165743475E752F39BDAEC4 +9297290510FFA264342A0AFE2985F85DEEC66C36EB4A1D46683EE7C591A89B81569A8566AFBCA268 +10DDB0970577A76EC8A066622606B08315DB0F2E6C671F3259C73637D773D1A180AAD66ADADA2A65 +95B5F481E5F59E51CBA876FA06D21E1D674CFAB46A02D267E20234324D0891E7847C13C69BFCEEA3 +AC55F2EAF753726BCEB0DE1EECF42ADA964BF9E475953302C2FCA804B70B779482DC9319B40381E0 +9C0096460AE113C19A2DC9157FA138CF0E7758F71008E71D0F7599744D647B09B16E3C795C56EE5B +D14D8D63E7A512900D67487975EC9CEAEF69572FC3C2342AC5D365E8A4BCF462006B5268ECC15754 +94CAD9A9E7A9E8D9AFFE49AF647C017743EC7CFD5E66F4E4D845A6BBC836849274FBD270CBF263F1 +67DF7E26BA91F21C60F96257C07523AC37A2193010E976965CBD75751E312817C0564E1C5AE0CBA8 +BD12B01122D07020A0852120680985A8AC987BC33BE863EEC52AF13435B6E4048D951F5BCE36526E +07A8661CF2538F69D1F223BC53BF5896437D1BD46F57D9698F642F0E99C7392D8EE47134E34DCE94 +D392949B418D9821E12CAFA8337323E8469DAC24DADC6AAD4A0DADD7FF65694BA3A27964D28D8EB4 +1179458F91CD3F83B8F119BF5E76184DD29CC4C0718CF7945DCECC993A7A78739363136CEC7F2FB4 +95EEA8CEDB3EBF14373A058758C442939D36774435554851E9519B6F09C31EF26B6CD997DAFA11DA +91FA9759F17B7079164C5B47B99CCB7A876FBAB1D0D5D1E1A2683CD6914E6B3B755939CEF1C9168D +30B2738C4349650CF86C90D2542FC9B90F36A494C035A1C86DD716014AA16E6B9EC7AA03B16554BE +C436511DD3097FAB1FD0CD49EDAB96F74E8FD26400FC748CBD9EE1EEAEE24DA30DB6F8734B52818B +3A5E510AA5C14E42060898033E7E36CBA9A64042CF94A74E4B52E37AC027C0DC69BAC4944CCE12E7 +AD81AEDCE642EC34CA23E3FF07B8CD35DFF19F33C8D4DBB56A52534F8A827BE47AD4AEDCAD83B273 +38409FD1101C4DFF3F12D3DF79AD1FCE65B2F419451DD059C88BF066413E23DE27D3621DAC2DCC8F +9F3620DAD0F4B1A6E8C9E6E8ADB552E1EB2C4B2A3B73986AD53ED9ED8911F82F750DF05CD2EBA3E1 +B0DF208A87FB5ED44C3296B803881C1D9776D13350CD29C3F716F0B5A8B8557812024BA70069BE65 +89AA579EADB1F657712DF2570843D7C5FF7F4009D4D232D3547DC8B92ED5C4DB77B76255E661FF8B +163C6F3856DE5651B597EC7C78B84F0C6C1D6EA3A82286F1D3BB45F708D564E139E81F473C705AB2 +56346328DAA64D1EA8645DC10FD449092E0634D9D7344B2AEC3C75F6B6CD8B3F3867FF3CBB0F556B +186EE9A7C26BD2D17C8A773055D9D5013BD2F937D697A770C57BDB36D922CB911CD14E7FA14160BE +19C1A052E297B1A2D682D4BBC9F1D2493BCD7CAD2FA75D904C5F5479179DAF7DC6A4E0D269BACA2C +4F2430B4C8CF1572FBDC750A05DCD5B09FA3A9CD6F2F2A386E2B3D4D8E257BD43A783B38E63BCEE5 +03EA96FF2C373181744A607F0CB8D281D7DB1A6F4076AA3E2C61914BD796EF8A0873F79F964FDE28 +B792BA99A20C3F1F5ED1FD189FB1867C84DCD6AF43D49420C8B1F3DCE7DBAE71DEB17FE45644DB24 +4F44B1011C7C768EBB7254F4DACA64E9BA87AA7CD0F0C4B2228FFB9EBDCF3DDE4DCED39399FFEB34 +8811547D025320A88B480943A339E2CD2FA3605AAAE87939B1D7901465A1879BCB4C5BE1A179E7E3 +71F1BA2E0844F88AFBAE9B78DCCA47AE8AEDF5BD3D458C7D4A7A08ACCBF880D1F1DC69C636628DF1 +EBDC5C42FF88FF8B66351F3F72D703E52F3CE91E4E00759753A599FDD863788E99858498B66B93E5 +083BC3501C39A9BA928B0D763C28826FD237E949EF0BA85CCA9AA20C405DB6D5612DB718F7B4AD31 +D253AE306E4D7CB615C59AE668D347A4E60FFF7B103F8BD0E7CBDB142A763BE88AB40EEF6B8FC200 +458D728930AD0F94FE52ACBF0657C4907CC7942710AB1FD8BD149A9C9DEF6B8DCA7DB9062AA7B1B0 +11ABB5AAE8B77893A023F9EEEED4A20FBC30F922282A7AE2F1ACFF64151013D6B8AC2EAAE58171A1 +0F80BC18C3BBB5DE1E22EBE6033BF83040629023D74CCBAB3F1923CFA4A6735E1DFA8A1B261FBF1C +397E26F3BA9C2629CFDA84DFA3D1087EBB19DDA7E2D76E30DC2E15B8821D5291DA1DFD73940E5560 +A8A6DC91BE0075E3ED8D9E8CAC85AC20768D868CD2DC45DEADCC8B59AABE6EE5B2F891E0D7CBAE82 +0F83479332BF9707486698FE196C72EF72B52F54314329FC498171782BF160E1110A19B8208FC591 +EF0F0DA71AF657B43A7CC649A8488B759F7B69134B4F9DCF79DAEBC1CE52CC8015F324C9D46320F4 +4E1551EDA6D86139DFD1DB814CF38A22A89FABB4F75FB896B00E769820F763486E86668253CC466C +1529A5A924CC337C48448851A381DCEF63A0A302B65203D6571A1DD1FB9DC0C3BD6AEF4891497033 +109CEB5A481BFE442249940EC54096F1D0F2436D9E60495D0ACFF967A741B30467D24AC6B0032213 +18666B951EFD45324987B10BEF4AAA0FF1DF6887377A7F70F555DFB9FF1001C67438A167A00B05D2 +C37065655173A7ED9AE342DFA1497FB1F2FED6098901249A085D31B66DBB6AC25EF16C106B0A6FF3 +47CDF66434DC3F0012DAADE80B942D522CD59AF4C31C1C062157B3D000B9CB86E2AA7B4A5BF31605 +8A0D5A148EAA2C67977FAA0966E4C3454E08DF14C2498AD76E389AF65D2C139A6D8675298C46ACEB +7DBE6904C373C06E5F71399B2EDA0B40AB96E8BE991DDC39F92F1D24797F9EC9F2FAE25669B43754 +E2498E8EA5C44B176C3FB3E8F7A7A1481275A461F2549AFC4CC73E28417BD8C5212C13105EAB967D +AA679AE822B9B75B372A99C7E82D6BD83AA2BA00314DA4AC51B9CAA30D80507505BE24BAD0A87C5D +5D7336EDF60CCA4CEC8201D243C3932F74D171E2409D789AAD0D04A7BB22FB6DC3AB92AE33FFEA89 +7C484D741039F38C317EA396A0FBB9F15A27D87FCBE007558799BAB73212B6E5FAF2080BA074724E +AC87D88166DBC1464CF5D41B99428851FF1D99246944511CF42C3F9248513E9E51593F253D89C604 +388AD7132D6A169E9DD888E020AC1F8BA606F2E1EBB97977E505D8C40853653D8F398F71CC9F8F9C +540C22A1E6195BA578AE7262FC845FCCF77B33F33EEF266489AF8B81A615D6A13464BCA58BEC16C2 +3F31D678F14A938BEC31272DAC3CCB1B2DAE577A26BED852FC59843176A5FCFCFA0AB7FB00D2309D +E55C82CB9049F44FA61F1E313205A76317C4CF529A4456019D970624129681F46A9CD7950B8B5C40 +61853040113C8115319E68B37F88D864C6957DF813B305D09E6A1716B10F26F2EF5C727FC77AABBA +73E12B5AE6416AB19F6563CE14046B715BD4CB2B1E4D315F42D10F74CDEDE82BCDD524A1A5460921 +9084CF1CDABFE72CC8375478B41614BC18A914903596D6FC2F361EE519F875385F4ECB50F7053127 +4EBDEB14A5DBD906A60817246042E3799BB3AC647CDA7244B7998AE4F3BFBE5C767FD2142E48518A +4217599E0EC2CF5E86C8C270FF8B02F949EE001D6A439BCB4BC7D7F7C8167C3AE0A7E59687FB8BF6 +F37BEAA164541B8EAFD92E9D152E3FD0F413C99CCC34FCD8AA455A0B55DEC846A5874B94FC95CFF1 +BB386B2A1E22CD1C3914264B6D5BD1746972857C9235052D77A6C0DD3019F8A307FBEE63A3EF12B0 +39B224108276FFA84021F1AC5B745C54690B3FF587B4B1710AC3533A67BCEFC503ADF1F4B62B2910 +B31965E364EEC9CC437CC40181A7320CD52BE9C546B8F1DC824312216C2FD8232E2BB8D40EE2E314 +54C09772A387F9520E331456C269F51A078E6ABD9FB6A68BFD5F557215B0BBD2227B8959CBD1BD4A +EEAB094DD18E891C61FB00933C0A0D76174D169C0B6445D34C00DC9E06D85EB086C18F3BE27DF734 +EBB9CF078AFF6514438549CBE92A0C0D25EFE4A527D86F158B4E9D8870C7AC5D6C059643A3298079 +CC20398324CA87273B86ED801057D797D91BC3CF2F96C650EE1566CD3CF8656CC577D38B830201BE +718DC9A494268177A5019546EEEDBF101996BE593631654B638C75A6BAA648CD1E7AA9AC1EA60F4C +D604071C89DCCFF8B3E430A57ED6DE11C5837E78956ED991058F3646219BEAE94E4D9381A33D48CA +9B8FF12B54A73FF869D0EEED7E098D80152295E6016CDD809173C57D1F5FCE908A37010AD4C4471A +53451DE9B4363B63437C374C598F548F145D3D288F42531FCF36A9CDF72521F1C0868FCEEEB1857E +A983F6B75CE245D875BEAD1BCB8819E5464518E04717B78BD6E335F0AD77B832AF5682062A1E2AC7 +7CD5EDD5DC372EE456C96D38BF8BF348DAC2B4EBBB2440F2CE97B4B337F2E23247E3E8423BFA9237 +CA6CEB6FB93F960CAD894A96F0371168A33222052DE9B3BE04B022AB95C0C243486E35197721FC55 +311DC55F87BC72D09B6C940CA36E6640AEB66C394A5949A604E7F15DCE3A008BB41B0EEF2840A357 +F348443B4DCE064B4C15E5EC52E448C985FAA1C3D6526270B1CC691009959A7620C9A6202619A19B +E410FF7BD535A8B2640AAA459DFDCB8F2BB35112626497E8A397D4F9E04788322A738DC8907CB643 +15CF63C95809E90D06EF02F72AB04AA61FE02ECCF7E9049FF9F3EF2258A75656178AAAC9F3C2A26C +001341862D526CC14E92A81BD63502F959066E0BCD659CB9B5A45606153DD77039B8C5D5B13565F0 +0D95A41937CF97089F3938E39659A64DC3D6046D0E9EF66544CAF8A206635DF49926A3EEF3FDBC9D +CCEA2886EC855F1821C4B9CE1D02A19A11BBBEF43A7D4D536715548A62802F64AF30BBCBEA8C7E55 +AD56C801D8A569C8183615A78CD393CA42C103F155941E845712C335F4ACFC7807202B92A983111A +ED241BBB8501F15560E8F2157C29752BDCDB274008137277920053D6D7DCDC626A574A82A8A34F1E +77B2FC8CF7C1A7322F22DFCB450259EB450C52B70DF3584A7C54C813DB41E3DD81253A03B02BC252 +346AF0160716355797B6F8210C453DD7E1E756FF08C7E6A5F4F87605E1DFF35A130D79148A57B7AD +12D94A129FE3F055CF974EBA09A2B13DEECA2E02EA818A58B81E8743004646C7746110BC61B86ADF +2D5D8C45A6A5461EB34497FCCD09E711F47BFA742C73F87B257B53F30CB68D151424DC3C210D3E8A +C67C2495A8236EA2D7985A5E1DEAC699D7B700E6D38EEE2E93B191BAA5A8A2C916D206C63FE63427 +AAAFED2B5784276FC21EEFF2D70E47C8540DCCC3E00134642B703795CD3702631AE2A90E063A218B +61E5B89BBCFFF84F567E37A31A9B349717A8CDB9C9377215BA838FF7469BC486B64EF2B6D92519C0 +BF0826E3652903F40E400689F5749DF86FE3DE178E21E20EDF9053081F6510D8F19ACD021CBA481C +484D30EAD3B84ED0190087EE478A17154B243346C3938FDD5340CF6E47B185E64ABDF44F8CBCDB82 +94492B91929BFEB9DA2B033C3ACEE554F0F1A7F8A56DF7C06A3583C1E9C5CA458D40E550FDF3E2F2 +E7BE8312D5FEE98543388EDC8A04CA29F1B82B7AB4ADABBA3F2C331EFF3521B2B92F99C4377AB827 +A989B423750D36ADDD2E286E7F3B694E29B8BC403693C6F7CAB5FE34F1E48C8D41B47831E8C3F5BE +5ED5142E3C44ACF5180CD41FDA149B1F4AED36812E42BC184227F5034220F74F67830255E1CAEC12 +66DEFA358A87D2E3B4B4E7EF30181570D0B2B43072EE0311C2C157D32EE2BEA8EA4251B59F6B61D2 +B4FDEB654DEB67AA3DFF4AD65B727F0D6B7D61523E4B44D99BA5CD33540F340A35DDD466ABEA4E72 +E504FC9BAAE51D231C33A8CE7DC2970DE4C1FB5B096A3D9C641EF77DC9039886831DDD01C4F21E6E +168E38BBDDA5F4308C959C7BBF36A42D042DA6862937EB20D4FA2E5927741A58DA5CBFFD9553BEFF +BD92E6D64871D8B25D9049F4E71970A8FF5557D1DE83DD24286D6C3E4770EE00F9A1A0B0063C9999 +4AEC75E84D6F9C488434D1F3DCFD0A8BEE9ED8257CA97E75E8B1285747184D6D2228EF95D4A0B8DA +252318ABD35C8398FC6568B294D90AB308A7675F9F160140F0A08C88AD0CA1CA2CF85E4D031CFA3B +87635F1398EB7DBC666A259F02DB6741D13E11B230025DD6DD64C438409AF109090058151E4DFB8C +0E9CD65935C4CC063CC6100FDE70896E23E3661C7FC1B8228B26A55903E997F80207EDD8863FA074 +EE4FF23BE585BAF708040C9F8CFDEB42FB8EB71D4CB6D7757E973E4D8C9DDD082712C23F868E1135 +ECD91250BB4335958B07C12FDA75EEB56BE19D1644C1F76A8811C021122619F751CBBFEB1D3DC912 +999017FA163672A1EF754C5CB78962BAAB76EC48461B492FA88F9897170DE857CC8374C8BAE417D4 +C78A56047024731F4A45145F0393A27CAB614A7FF747BBC28E6880D4D01C0A6CF317A1DE5BB5ADFA +4B5FBFE0C57598C79F25AE57BB797A489D51F85A9B9CF8BEA64293F8FCC43B0D5484DF99DBE19152 +692CE756F6FBE8CE5831CF4B8A5AF47524E272C45C62ACBFBDFE7E60B05BB1A1A6AF0E9210012014 +69B3DBB49EC7B23A363FA68417B7118DCEA71D4ACA2E36F88C6DDEFB70205DF3AB7C74CF65CFD01F +F85FAF99F172689737331D4C6CFF7A29029772F487FBF625F17BDAD89B4AC076948277B4ED687840 +301016C2B7AD4C6D02F81E88C75B7A04D724E234E38A38269351582245E361A42C75B8256AFD5624 +B558ADA2190F960A896BBAE7A8C57E76DA10DC29E69BBF3AA86214C001A27B39C1D17C548DA5601E +86A5CF53E7B1896BF003AAE9387ABA9B102EB1E9002DD3754A378F3E49F2C6EECF47EB1BAC2CFCE1 +1AC0C5CB063672D32733563F3E1E891B6073739BC53AAA0043FC45E90E413DFBD4548DD320B681ED +70A7443A233D79E3F038D26975586E5CDD2115AA614727B1F6DD4024B85CCCFC79D10B7B6AFA789D +B37BD0E8C423C1A4A8681B5FF3A9FA1F61A46E46C4B1836D1AA41A89264A7F4B1C259E4B10ECDF37 +5BD26A1F412FE01FBDC03368FCAF48AA0EC28B1BD603A6A0D0DADE66D14C9B7285569230FAB76803 +35BE104305E4B748FA99FA31F23991608DFDD2097DA292551136F255051C9F7EEF3FB7C7FDB4E651 +C3D03A4CA357B587245236F4FF3252563F6BE08EF8A3EC09BE2BF27B9120F7D37801F6999EFB1C8A +D1A08698CC59CEAE2CFCDBF6BD8F94DEC94F7EBF33AF05F52C85760C63950B455510C6AB9398D09A +C288EFA09E8F631A59B03FBBC75BBDAFD675FFACCCF8ADF71E815A4A49F14BF70E42DB0B7347B528 +4E234C24010E2177DBBD57648E398FA6B54571A37BA8C989503594D03C6E60871A7F964599022154 +02BA168B8D1D2685F5CF8645D5E11A1769473027F42564C2966C10C0DEE1EE1B6975852A4870D492 +83A470E623337544A7CDA5C16FE2855BA2A548511FB4D4FF2E3E78D108E4C734F64EE2F12CC9562C +BDF363EFAF5201B673AD00583FF108AFF6B68055A5F299452D176EAAFB92C84F114C8C22A05EAD65 +64A3371420EA9E646308DE97D40705E1638DF08704FC90249CBC0D2D3E884A4562CC27370B1A9738 +9D8EFD237E644A7370B8B38ED1C377F522C75F981D878A5E87101E621DF9D85C7207BBE5A87CCB60 +7F93A2E52F660E05C83A7A6CE6D01AB4B62A1EF8DA47CF97D4BBA0FA8EFFA9C0F61A325A97ADA694 +45F23AB1FE27A66C271639F839203040D44B11ECC6E805FBE88843B34C4FD52D1D3C6C70FFED433F +C04501FC20536ABDFFA429B8DC8192B2D45DD9D646049CBF40719C3D674773F9676F9FCF32817DCB +55402A72C56D74AA4CE4035687C730B6B44A9CC614BCA5A3FD17C170ED949E588EE45E89E18B0766 +2A6327FB9E8475C43E5DA1B0AF07C23774B19C9EF59281F5D884990D6194170D8293A86DB52A0FE1 +7E88DA82209A00A16BD29B8B2F13FD60AA25FCFA9745F57C8216283C1D6EA1C119CB9B8D57C00419 +5210FFBD56395A3EC2D3098ED38F389EFC0324FD0E55EA339B3892568229D8D3E205A821E8219FCB +1A7713FCF3450F8BEF976CA0BECA47376A8CA73DF85B340C67EFE4534D459617996526B5E5D3D19E +17CC5449E5EF2B82B2C4C2131FF8A19FCFE6A186A9840D872D85C40665A7A04E67EE26B8BC9206C3 +5B44C8F8A1AFC3867D96DC6D48BD45063BE25B882E9BC0D0948C18DC870E6925818E1FE17D336217 +F174EB4481F5C0ED37A3BEAFAF4D46F857811B6728BEC461AE6468D87A736572F4FF95B58B04564A +9D3C22754587DF15495A319D822B838461764B73483C1F7CB930EECC6F7424841EE10E4087E95120 +2FE88A391375C96BEC4480328A54740213F741105B12A39F19808F3823507B88115D468C61B212A8 +ABAE7480E39BA52390A1892C7EC50271156B4E8076FC3ADA222695DF372385DA7B117A29E04CD2B8 +0A320F186D61C963FBDAFE9224E537057C49E82E405196AAB621B5FE4011E1782A747EF935ED8BB1 +1BDA39A141CC0BA42D04AE123383BC95A1D03A85A9440010C3B9613064FFECA76197E10919BA5006 +F35837ED9BCD7DE5E6D968AACB6FC91178091FA467EF6FDEB728E17293DC89DDE5A5261FAA95A2B0 +000FC750E7073900D4D88247DA464613ADC2B3903A6132D96AC0E1C564385FFBF6249DEA76BEA2A9 +9160632DD2FC2B99133E9F2F470F72B45D6F18B45020F604B06CD9174BA3805DB60EB9C5E6A9C789 +ACE76AE9C79C1BD34434E95E501BC968633AF93FF4883C6A596776254C0C74993710327086B2886B +02FD3E42A725A03459CB36EE34A094139AF5FCF487D3DFE63FAD20BF0DFB60DEEDA2ACCA3510E963 +189D1256EABD81253F7FF9D11263FDBC1DCFDA3D1EA2E52005CE3C605C993231258A717423F64BFE +EBC34684EFA676358B9B543C2042BEF954829FE3246A879845B30EBACB43D8DD7A20FCFEDF763AD2 +C5D20A798B69E08722DCE6A5762E249ACE3055B650D9E110599EA30DE5C4FE7200D5A8DA9E1FE268 +6350D0DF334877D0B9F6524C552D0B6DFFAE125EC4C18F7547BD51C14288E4ABB7F8A1A00458596C +390AEEE6FA308AC1F788FAE30D7F8928AFC91D4DE6352D20B19D8D8AB122B7378CB379C5BE7E3CE2 +922FE667EA057B5D7B3F0B51C7BF0C85F87AC2F360D82C38964F4DABCC9104B32F0FB8802235E8E8 +D9A5997D392259074C00AF2CE1D2BF7B8E90E2E2AC34185C68A03BAB8B267778292B227245D7FF86 +70786E3F746F86B9D4D17190DB859A0E144B2A61E6AC9254DE5DBAEF20E2E9DB0B2FF654B996E962 +F55E465DD238BD1643CE59DC2B5A58B1E6E4AE2DDC2D74D79AFF3C34E4E593E051FDA236B79CC0DB +268D2A89B1878051223BB8F33FF99BA87A4811C0B3BCC01171D0A731EB732ECD8749D27952C27886 +B252F9C3D190419FD2900987A0A255B9753FB7AA70C37462134C467A2C4B7920BED9F9E86F8F98B9 +6D00AF8B05A4BD5F14C2A0D914A9A84160D554FD0718F50ECB5DF5E76623065852DAA74C9AD6DA07 +A119DF12C3577FE276AE551D48B1C5CD8A50E84DEC9CB0840520D78FA7F9A7C2071E28CD20EC7649 +B991F3818CDE295CDB6085F24FCF93147E9F4DD084FBD32525326D2EA147ECD5B6C9D9F4A7166663 +AD18BF234E9CB92FF72138A8A49E73E527E9A6488A4CA808AECABC94D693CD2C0C357D285F65006F +A2F9197F61FBCA6EF07B013E2B558AB531D2FD270CEE7FA8E467FAB885E90C5884843AA08E2BBFEA +0AA575643727BA18ACC499FF34E3438645BE2AA71EA491E54687CD305E12BBC94FAEC848311AE816 +495B013BC5075A2D2AE54A7AD7C9105B64356CB51F18C2C28E3A83B9D81A4554DBEC9BEA9A660CF7 +E1BA89E6D4DFB3EEC6A3DE3FCDED9B2D614156EDAE8CFDAD5FF0EFEE31DA3E6A54D94CE9453A1CAA +D9756D91BE85315F6514BAFBC821EE810BB5D8E1B8F05F64F3F72C4B35D424F7E4DC3AB581B74ADE +B6D6297CDE7AA8278909F269FED79B7DFD39B1C0338E01D556C4DB9CA3A8578ACE3EC3D743ED4B9C +0145E4525E8C315F7A1B98584B975C70F0D415708C8CCC13F848B1D36AC8249B73638F95DE0CD27C +7EFB52BED4339EBDA4812564D7A77416DDF4CC88CFB52D07A252D89353C6826CA1832A153242979B +6CEE783ABDE65C8B40CF4EA7B42B8DBCC0E02423DD693108006F6A4AEBF053B666C3CB63D1861F86 +EAACD43BB9BB6F2C3A17293C189331D253B447757EE7CBF4518BABB73A1D44874D7F0625E6A013C6 +08E991B4AD17A9ADB36740D25E3E35B459B422F7370B134CDFFF3F3BCC4C32B4E9EBF6A2478013F6 +6933A1FA9403A2F1161EC632F1F04EDF95ED0F33DAD9665D54DD9DB2564E51DA7B65978CAB50D6DC +1568976E83B056EB0E3A6758518B6E17E9EBFE49B72EB148B472BA144BDC2AC95744C9BF1258F0A2 +E47470AB0EFF90E190A41108914AB8C1ED6B11E0681778521870E80C16AF2AFC723CAD8719ADB62D +3939D3BC8CC1D8A4E07E9D734F54ECA33D936D2C39D5C8055739C33E53359BD40E576C11E93B4B4C +122BDBC9B1BBF44243AF4F0BCDBDFADE68C526B5CD74E29CE3F70D62BA83C489034111FE8E4DAEA2 +F01F9D938ABB532DEEAC0E329F42453FF5C15DEC2AEA8C198323C9E8FEA55B3F5DC4751D2E2E16B6 +154E7F2ADD46860E9CA71DC114C99D80E7EA1DAB51E925DE161CEDD678EE6282AFF38E3CD0E65954 +9C970613209955A3F581E1ABE485E56402A3DB0D1E9B8A9DFD05C4B0B7F97FC6D0EED0B69AD6F182 +B1D028ADD2F24463834B13F5C1307F91D363891824E81108E57CFD5211F86400D3E96B107F3B1FE8 +9C4908649D04A46DC3CEE0DE66AF03A7FF9F4DAFECDD6DF4D93784CC899B527784DBE0718050FCE1 +85BDE3F39DEBCDD660B2488D23AB1CFF87B0546D02B48E7B7724C9E87B71BF34B5D6640E0F6ECE47 +B182D41C89461F712849C6CFDB7E3F5EBC1ACDD12D65A422BA362A8FD6CAAC5104CCC5AB5FC04A46 +E4309ACAC83D659DDDA256CCDDD1BFF9AB3622450C4FBC89C82214F00C42FB0311BCB1B722A691ED +839CAF9024FB1671F18E4639C96D84718C663A4341DEC037175C6BBD288BBF5A0478298CA726567A +9B74C32A527339C666A294A17F6821CBF243D13EA4B1603C292953308B566653423E7301A032E5D5 +E2B93F1C1434893633DD19501AD12728B5A1D9D36635B589FA2E151140B543D7C5E469AFAE8E80C4 +FC1D9CB6C3823CC1BB7EE40AECB58CBC1465792226B19E0FE79235115F6A3AFE19F98C5DB63D372D +D7C041CD940F4F79F2474D9CEEA0334FA04A97DC9773064895CF11CF73F11B4684F06E48F4469F6A +1AEB2CBBC52994DFAB3319DCE3A0C8C2EFA9627496F8CC84D3DF3BDC4FFCB61672780F294F453278 +AEB9262E66486856D37B7647141A82E049364ED3D03F925284A3F1FA3DDF4C0B48B3FE22E7DF9ABA +239D33CD300FFA8FD4B96192BD568FB18D325CAA8E1F1FD4B27527417B034841FD49E4A77F217062 +3CC8B22101166D80361EB15FA9020D24F61007B0A8274DF9DFCD8E97C85568E76D34AD5DB1779B02 +F034A69CCF9D4EBAA188EB3017EEF5B22A0A552696A574907F695098BD8A4849D5C8311F129447CD +7A3CF88B8191AEC0AFF30A38A9AB8135608A7829207A7D242F6E1FA7DDA19F5E4C28560D42DB4405 +77CC0C5F5803EEE897103ECA0BD944E320AC26553BEE7852EAA733BD13DF760056B2F5BD1243BEDA +BC3C1EA0531017D74B47E18F801A60074D6DF849FD0532234545E5B5E112D1E7385341D39A89551C +80DC2DEAED5D5DA2A4BE5015D297324E92BE64C68428132E6EC654DD4BDCC6640C68835FF8A05E09 +9604B8CD43D3AF2B2FE10C8AFEDEC5A70AF8509D12F662338CBF166D9452CD36331758AC4F4CBD7E +DD52139AD27DC52569877FE709F297444C4F31899D1945C81B14ABDECBF31DC463A4148F04EC4FB9 +703C158216C0FBE65CCD450043ABFD4E65BF8B28CC148252E9F3E797EA0B57B8721C94CBC2EA602D +F2C57E87938C887A382D2659226463BC7D6A1DA87F4A341A59BEA458177D3F18D1213539DC0E301F +6EFE0111FCF6921368BE17CCBB7428127E0C059C2C5ADB2A3F0197F0CEAB77FF7F3C027A8EC3EE76 +CF5C986EB47CB60561C773B3A2DA47B5A35394E29373DBD5C3FF4C9213A89AED77CC4F3FCFC49EF6 +EC7557C521979A546983C106B3627B5FD2D71CC5F08A32BF49332A89C5DA71AFBFB94C949A91220A +B1F885C981423AF93F73BC1CA4D92D9DBAE3EFE6A76E2DE3D0F74FD3255820636E3F1A6B7C185306 +23C12AF90CDCD2C0A728521E9B639EB6345D1DE8FFFC3B19C72E7A93823DFE3115E9E7BBBEB28CB7 +3DB121AED8920D47D8CC08EA2E472E39A4CAD5881B5C4204F2B732AF9D5189D25ABF413CC78714CB +01B1D8CA5565169A919DC481F6D2E67F1D490AEBC5CC62A8F62C1A323EBB55ED35AA5C8D6F8B970E +93205C2701CF4817BDA994FC16197B469ECC5F5E9DDF0FA05640C2E571849571CBD26402B1EB1E80 +3FCF423345007B9B52B13E3B034E8CB3984B925EBFFE719ED4F39F3D0E3343316A6FDC26BDBEA88C +4366D3B2F851D2B244CC4408251AE2C77348CCE9DD8BB9C89800B572D38C5D1CC34C740BEEBB5DDB +0A8BB251655FB989840D23205D16311A9FCCF7C85F6DFFEA9704492A4E7A8F6C0BDC29745AAC2ABF +AEBA02B0E7AEFEB92BA63AB0DF844EB09D505C3DFC1058CE42CDD8043B76398401E1DB862FF9F76C +05E8BC6260A4443CF494BC1755913D51745BF45ADF2F8C7A9546D7EF4FB11E9D94E4539632C2A396 +06D04480EE459408D7A2A869807A4C01881C1BB21C296A402B5E6E07093D833C3DFF075F4DD426EB +87B1B8DE16C146DE79F52F5943015331EEB852809CBB8E1D6460AC4D176FE96F8D19F6CCB22ABBBA +A27C4497D91312C3CFB5BB913B314E43D2EC6AB6897BA7C34CF2CAA6DB4BD69EB5DFCEE0AA917D69 +50E36A68A4C22A60DCC69379D47544A58D640EB10DFE120FCA843B588CA8B94F7869F97609A6FE03 +AC86EC1F7CEAD2EC8E81977D1B946E459DFCFEFE65A7BFF67E66F5F78A45D8DF65AF0146DF74E024 +FC042328886CC1DD7779F49CDBB750345CF83CD678A6A8897577299DEB38AD665DC4F21CE1892A18 +C256F318107DD3E9245C1AD3BC93CEF7B7BF057E33EC9A3F953251261AA3D1A8347261E70A46F777 +3A84F3D4D1A0DF6DD22A96429349DE0D180310E17955B10FBF53220EF6483D03C650A8D5C16D63DA +F65C21ADCD6C2D0B5D4ADEB2F5526AACF7CF42F9A8BF4832FB2D4F73F3D5FFD984B572232F87BD3E +59133ED3D2FA19F7856AD812515C74F7D851574019C532C25F8E163E595FC9C83E3E820C3CBF690D +A62578A980FC0803EB6DB9B1E90E3256BD4650816ABE5EA86CE65C2EB418D0ADDA5F3EA04E17AA8C +4536CC471AC20236E66ECA3619F161DFEFA485386C30EBB86A7AD930FD0AADF2DA69DCAF26C0F677 +206E2030E3B15B3662C0AD03DBC1636EBFAD1F2F2C37F5FA9856B0198C5B1D80B69C5EFFD94CE071 +5135C649C26B9BA1266B0A5B270CD08A706166C0B320915C87B27DE21DEB5D7E4806F6E700B7A06A +4E29B629CB40761983E9CA8E34E869ABD04DDA190BFE5A6EE8B22D7E511B84EA584A84211F27AF89 +18DC5AF8A1FF2D360B6BE3CA8E66BA4CD2CE6A25E7E89406684DA83FFBCCCCBFD0844FE3BECD7DE6 +7764C59C022DB1168D585FE25073FE00E30218D1DFE115CA1FC606AFCB04F2A082EF91788B6BD096 +84DEA31F20034A91AB9D971366F97B5009FEFBF1EF0AD941654081B1E8F0B2EA495069A1DDF11DC5 +6857D29533DC857958B49D1A0779732819FD22E437084BD9F3C4F2CDA4D12CA14431937AB63A03F9 +C040AF1D801F367ABDCA7302E18A9050D6026FBA5A5A7FAD44E31593173CDF277CD737D1CEF59FE9 +684252BC0DDD00A80E023B88222494C1C8C0884230AB11D1083225AFDCDBC1E24D4AD5FAB396D2E3 +70E44A7571B230660D510A5076D8E35F7DB72C0566DFC119EE1B8AC3C0406950A3C4A4DA36BDE297 +040A27F70753A87E6CD593DC6BE9962261A99AE5949340C5D45C94A9AA3DD636CE8B497BBB812345 +7C824F443A53B3EE595C38983FE3E07DBDC6ACD55CAE8BE1081AFD4857A5F52A3C925143507A3C37 +F1992CF72ED0D4C48D94AE6CADDC3BC87AC3A3EF035E02181F78449E4B063B0835E827644051551C +1603E2EAB5875F28FC77BEBA6923428D5521C698C6B7F133B0F689F105FDBAC30A8ED2F29F0255DD +F8A037B81F04EDF004CBE639C8DB0F94D0C5DB92D34D66C2FED66CF8B895AFC4E659D08388EA44EA +E83CE459E5BE306750A682B627802990037157339BF142BCB9C08FAFDC3C3FB16DC3544F62C6C7E3 +3E20CC4FC7CA21E2C3F6C546CD78DEE348F1A4C8CB548EF20C049678916771D83ACC9B7B22784AD8 +580134471A3C79BC86B5D6D0D305C32E6204274351C94F9DF45D9B2AD5B5087A89F90D6AA033E4B1 +D1BED022F36147C7ABD2B73134DFFD50907258E610C3B20949E141172B1C6A76DB238C375021CBA6 +645CDC26B717428B5A9B4D3F32A4B1E22FEFF3BB93FD889E1DEF8087718D5E3E650FE4A3330DA9C3 +7E9EB499DF5A342D8BA4C0A033C3347CB25A31BE143ECBF91384F2381E323E7FD3A82A3197C18905 +3200AE2C86B9D01AB0B289841EA7E9E9A26966E0DEF54DE0B85D8DF084B8C590081E444BAF1E1F60 +670FA12AB97159318624F2AF1B5EC7DD83C1073A99398D2143A52D10A13C201FB356BC9E90C63BB0 +BC2D4C42AF4A8B9C8C4D58A1B32E0597C63B3F8B3E893BD3BE8C60231838F1BC78E73A6C8CDD5E7F +2907F897FC8EE99BFFDA7338BCEFB5AEF950E5549ADFD207AEB15846B509FC57989883642498A381 +1B8E5CDE69C05924EFAEC232FA4CEF302EE3251366ECAEF57D25CFA3B4A9E6397D996F421C900BEB +CF73B038FE7B16FD0A1172AC2F40D19CE0B02FCEB8BC47DA5344CB933C7FEC950184F78ACB32D3E5 +E290E84BE753B9E7A7BFC4416CCF29D023760C06CDDEF2505806A65E1508990529245059AFD301DB +669D41BD72BF7A80A9DF66B876B3553FDF4DD38D15289AF7A1AFBC53FFFF135A6348DD784AB42A6C +0D6AA330B069607E2DF3CBEFCE79D6F63E274C9E73A33EB85246D5EBB986BFA923DF68B2B8CF82AF +6C33E785F35B25B1D1D614DE85A4F4510ADFE42D75B5FA5408A59ABE53859E28B3D000EB9C6A7D2F +67C91DD14C895BA87B9CB57B851E5193FCC2A443AF85FE28DF6F39537F23A058BCF81DD8C04CB2C2 +5040300F4C55975E856DCB4E21E2B5481BDCC05601942FB25BB8A6B6F93E2C2A33CD478B44655657 +C557EBB080179EE5D98C5CEBE0B25BFDD952FFEB258014D7A5BC4BCA4F1A23BBA73C454B12960451 +CE1752401B0151CB2E01D5C72595095EAE91D8D3BD55A54A2AEA89239FA176FA7CD6F16BB0733EF6 +CE6E77763A23AAC77DA88C8EFA7BBB2991E472FF2075FB25A75ACFA70A04C28764F4AE4C12051B25 +B120CAD2E3044DA35C1F94135DBD69B10DE147321CBBDC814CE99982AC1D76CE3D3330E41AB31F3C +76BF89B95EAB81AF3464C732D5B1411D97DB36C9063537F64756F205B16ED7058E2CB1D6946C00A1 +A0CDA9EBBE924BDA6C7D7B605C514A98133907B793C74CA858E82DA3519188CD974B34DAA74265DB +5BC8550D5F0B1173ACEB87458BCE2AB1F96996C811699A0FE4A9B849D39023725E2B1EE7E426D30A +6C5C75AE6BCEA6DB41E4EB2035F7F924E6B9F0DCD00EB2BB014222E55FE387FBF5B9B7C04F4688D5 +AE3529FDACB38B5EB0AF5C3A874C1AA6B17CDA8D1E22EEE05A3DA88449200D3D0D002DB86F6C51B3 +37C8E19F338E7BFA01E1202612D50E210140947D5F350E84F790286C3F679A5D7E43BCDC337265C2 +631527FD62D598B7CA1F5835C0441881B97F5197901ECDC4F195BC665A846823D2E41417373F8639 +567B228FE7B73D781F07A361AA49C3E9D80FE5B2A32C4C1E575D194E841967B08D10405FA44EEE28 +47DB9372C5CC931E50469532F1BAF577F680BAB4E30B7E1CFFA8574ABB679789F69A8A1BAC07B7C6 +4EF5CE5EB00E97B36FBEACA9BBA4A13B0293D34BDBC77AD1FF88E5744AF009823BC262511C4724DD +585E7E17D90F230F7A5861B0DFC42F0B4E49A04EE0EE4DADB908479DEF8372F334C53D2BA5D855CB +39DC7C9550F9D0F7F77E82D5A59FBBF34BFFE92DC9E6668B68FEEAA4F20053433D6749162BBAC5D0 +D428DCF2D58D49B127FA2E674EDC7D3613B1342F4D0ABD7F4C5B049FBF78E804D5F16505AE7EDCBF +4D6FA08D72890F5D55199034572AB4B0C9A7E7F6F5A403198864ADF113CAFF5BF9D4AB5B16F81D0F +C2188FC80875E10034D12E30C0364F8F72797F1AED525A2712A40D44210B813DF5A29C84E9F6D51B +1D60A5F6F938FAABF878D29E6AB252D95D05FC1ADF5D4CE1C9E585219112112BC6CD5C766411FBD2 +2731794B5DE0A27AC57D3C57926807469C360372BE529098C350EFE2154B87F1205A57A0B04C5206 +CC4FA66B8793BBBE492CC3271FB4F90A28D0066E0D7F63B8DD01549A05AFA5482C29560ABD628568 +75CAC16100087540162473498C14087B29B86B7BFAD693E81765CEC781F3FC80E9C7B410E9B55B88 +114191A1703C638DFBB469ED1DD8254B1407003A319CE74AD419B077F17047A01F0BC0AC8507191B +F72D77D9333C9DA8C9DA733EFB5305F49CB8C7BC451321ADD7D896395D269DCDFDD084EB3AA70338 +6C0697E962929651164135C094D9BB1C9B949D5EEBD3BB17F02C98C813CCBFB23C2C26218A2F4C63 +9A8B9DFF2C29406037F91938A5E1227310728428B56F48108CDEB33BD3191ECA89F947271983DB77 +6B2BC897A30EECF2601EE3B2A6F0E135397622AAC1F2DF523CE6E6BC720E13CB530CEF4AB9C8273B +D3D81563AC8A8E6C44A195112DAF824BC7A72FCDC4E129A480717BEB01085DEE65EE4344D0B41EC0 +BCDF842566B1D9F5353B1F6A063FFA6CDB06EF634C8BD5A7A63F991D178F56EACA653DD67685CE49 +E98C7554745A4AC533217662D23E1D6937135D13BC2208EB8D50560A2BAAC319DFAE478B6BA4CA5E +DA20222F0E9BDB0806320ED1665B54A347DE0C42E9F77842DE4D188E7E824EB2F0D7AD163F05480A +7FA99C5A603BBC5DBC843774CA66E889B945054C0ED0B1A4BB14324EF901B023C208CB95DFCE9284 +89789690CC45BAB97BE449F8E2F5AA9276C0571303E9788C46E7F789555BFCDC3FA9ED8DA8AD9BA4 +8B3AE09404664391E63A989EF1E24BB464043AA099E4F2D796E352EB277106D8D81BAF2F8562EF46 +BCFD1E0047E8018CBD973021DC1C1D821AF03F083F0B088A62EBCF2BF6C5B0FCFA441AAD1625FDB8 +34F943DD47A5A42EB3E9A5B49641F797C288B799A64897F1346070461B6D535E0C4ED099199C387A +3176AEDC7DA7E7D9E118E55565092A36F7C74ABF281720C0147F4E4F37D49436466C61FF12764E30 +43D8A6D027E70537164F0E7942F4ACA42BB2CB136177EF7197E76F49AB403F741C0EF902FEBC471A +D6C627424320A8C3A1F04C310C511B3F91C3937D9ACF459999C18A33F2C852EC38CA806599C728C5 +43714018C65E2C5F430F6270AF52AD71ED38813B60440779455F9529A4A1623CB9F5422B9216F9CD +BA913B9A1CD95DA225E254E8101216085020660509D03A034B5D7E32E3DB5E5962A9A27711D4C3E2 +9CD84057F7D0D7E8000947AFE896F8523253391D2E11FFFE523366B05C532D5629A90741EAB3D4A7 +31D3F6D4F03FF93233DDF88BB1913ABA22EB9AA6311E3144381DAE29BCC8639958EEE59ACCFA06F3 +5DCCC63E0609F542F3EE5DFB1CF718CA3F328455726F8F65E23ACD970E4049225998371B63E35AE9 +8DC54D8329B8DB0901FAA63129EDE21B158776981D4D094013C096E9CD020315D123C03DEBA21E97 +E4B584B4BC0AF25F5DCE53C2DC0F3E61F99BECAB40799478BE7F5AFD7F68E23EF50AD6645C967EE1 +1206B6E791769428ACDC370D64E4F2B3972E0E4F442297199350663D6E772FC6777A9B9DE215273D +082CCE4E8678FE9948DC8D5B0E459CD02F1645AC5620F3571A40B4D5A17DF5CFF48B6C843DDEAB5E +BF58FE13D7DA08E8AA7902119248B3B151DA583101CF80853B0150FE05BDEDBFB50A7FB0F65728C9 +3B9DF48CE8AF1DF1FAC25C1D58E1AD30274A00EB54CF2F16029E1AC0A0919C0655474B9A6936AEE0 +FB74BD185FE7D70BB84786997D34A40326A74356A4AFAEE67B6B26D1C1A7BCFF8697B55C816CCD77 +312C332A55315DC54F9BC0A0F12500E0A76B3936292A3DA2DDF5AA8CBB9B5DC32EDACC4827D684D2 +74E65B8B76FB2C2B19F7D5607523FA953E34BB39032C05B1C1244304606C55660D3CA8607E764EA5 +B03DB7FCAB5CF7788C6E60EC8C449BCAFD90BCABA4132B6CBCCFF16784FB59B36B77CF0A9EA572E4 +CA0A01C725A6CF2E4500CDDF5BACCB9094D48925434F044118CFDC2696AF5FC0CAB3884107ED17B9 +BDE0C0104B1292A1F8C99B06FC4A6360B24480BD59DF0488641899B0F42B1311B582717BA7ECFEE1 +4143654B5371C8B9B2D80685AD38D897AD1E64875C28C7020A84FBB3A3BBEE16617DCB9BC822B7C5 +9C5A18C0CF7E80163ADFB7AA03B7CDE8497C1697D90F2ED90F813095C5B91657FC294EF0E341DB33 +92ED860CB2E0AA09293D0F99AE9EB54C761CA2DB1E51E1CEAEAB276C7BD916C68510D72D9A67468B +09B3C39A7815628FB126CDFD5EFF59CC8184C0D35A5B5960F824BD175495DD3EB12A4E96008CB13B +8C5745303E66CF8608FF27C4709C1D854EB79608E52F068FEC0151A74C125EDEAEA555C198FC0802 +7BBBB802835E1D435077AE4B1CCDBF722354F6C572BEB1376D3E342195FA80AC9722EB2F46E44DE0 +5F5A227B731B8D4A4B6EDEF04AF2C5DEC2EEF8FF48C5B18710ADE3DBFA0C956505B6DA9CCB7CBB83 +4DB6CC754948855D833670FF0AC42A4773FEA8322BECEE04CA74AC2D66855132D11A51524488C547 +71B5B7A512796D7D7AE0F9C1FBC9CBDBA0831074F4D200349D0CA40537B92496692766F020AC43AC +01DB8B2AA2EFA9D21732BE3A315F6CAA402BB2E61D40DDEBDE11276D90C2C601A935C168BE600464 +76ADED15087D54A14C68EECBBBB590927C1E10D291C9285334CB0C80EDBD392BDE4D535EB61F8E76 +41F58AC1DF5B1C5A5D91E3E27E05CAF7EC97ECF0C85B6425197AA856521ED701E5AEB82A7F52A8BD +7DC97D5B3FB5C99A5DF84D1BAFF89072922509D76BC6EDB15CE5F9EB8F4154BEE1E82020240283BD +C83A8E49AA9A2649B7955D5C058F2818A63BD0BFE7EACED4A49063C489A626277AE1246F721C9926 +E2A2B6C31045FBCD235F3CC58BC4DD6C57FE998EBD1E9FA5154652BE3A1685BCD2EFAA079A3293F7 +8142A6473822FAB627927EACCD61B3E99C3077103D2D19382BC7EE15BAD0FDE489602D055A01DBBC +F91A566974559D1B477C209416887053169C3F8F59955BE4DE82B60558CC9AE15602A93F029F6B43 +29E0E62A03982DB32F5229714EFA1491A7B24AEFE18FEBC2C93DFE50B3F641B51BDD33DA38871BF5 +243C17502D00AEA2D9E9734E80A96788D4CF5BC12A42BC386162FC88A7435EE13200C1C2C6CCC5D2 +1A03941007B4C4291BDB711446CEAF27148104BB240357D5EDA0EA5A5CE27D4A83909D75BFC05D75 +F10AA74A6DE37D7DE15C1DDA3AC3045DA6CD48323D904E716B445E5E096FCB379353ED70CF4B6FAC +102C762711079EFAF13FB74C9B47AF75F3F6BDA2A4647D2AB47ECAB64DA6CC01479F618E8D2D0A36 +45445E8744683CBBC560D47C98078B84206E90EB839B02D37C852B8E284463D4E4D890203C3D5B20 +352110034EAD6BD7F41456B807E1DB1631A9D499E52E9D9853D86728B1A2E511F40F8CA1E4724A0D +17ECD640B52FF6C66E28693D89765FC391612E5889E77423EC85CBD0A038B6BA98B607701DC0C4B6 +6B3B28C7790A1F1EB8D051DC98276DD9CFEFAB3F65C1C928E48A060C992B392A43E56EAA6DED896D +EBCE71F8245BE4687F2F1B8FC0F43ECE8DB0BD0AB0811C5CE73CBE336023A0D66168B34A95B4B0A7 +50B3BF1D197E3C042C7914FA731D7831AF798E9429571CBB977E6258244E84701E5FF91D608F98FC +3D68A4EE5B81D5FF38B6C184F6118B875F022B4CE207DC7B37E1452DFDC591A3E506AE82C7E7BFF0 +011B0A3DBD616A993FBF878FB03B6C9F2055A2B095D29361F8253C2623653687FE0AB98078F6AEE5 +FC2C2BDE0405EABEDB3A33EB7F04CB6837176245F190C6BBBCD64522B12FE7F9CDCF201A1AA8A19A +7BBC4AC064B4958F44AA0F8DDA23835AD28A1FD0EA105DE2F395385DCCFBE2261DC5A89A23AF606A +3985E5038706B1FE0910400E16BF008F250F3BDE3AD806C735495D499F16F99275010478FD2127BF +7CEDD6B5BD505FBE9BD0065B4A7090C9D27CD5B36C3AD33E1B31EB6D44E375003B51B909DA50BD18 +218418B3CD22B43278B144BE78406EAF16C7DF6B6C1C6238004AAB73736B38E168441DC16F9A5CF6 +0793A18633BC43D78674D12D38CC979F7CAADA6EFE807CEA499CB9FE616496682A66E04BBDACE1DC +112B2156B9B0B20A58A8CB43FF0EEDB99805234B9A5789762AC7D65F5A319C33F4F7438CD15E06BB +80A7A97E976E8CEC23F4C646A5821880A82B2F1DC27767F090997E91488BFA15064B702F864FCE65 +05D6CEF87D2A0A12B55BA189AF269811E3B8B850C8401F3906C080D32618D9698A766732A40A9FC5 +A94E5BDDA3D028D823D6B603B6D17DD046DE181FD989EA0F80B4CA62F7973E4DF5E032A31FE6BC8F +5CDA678D4A72787EB8253EA5882C337CDF9AA3E1E7D9536DD09B047CD8962E773F72F6418A3AEF5A +289B3406C152A50CE7BD4B493FFFC27F6AA52F79EA67E362FD92559AA4F94A2F787F6C735DFADCF2 +F08AAF98B80C53CA5607A94F25F04AA65A70A75937840E73055B3D65FB054C63E2E48E68488C9315 +A13EE949E03E46723C11CC759D222CBFAD2E1A87CAD779B23D38F7E2F660DE1388EAF1CF4D18994D +75C6CC63F187FDB949940C18B537A0AFB12AC5F67B0283CA5EFE2E764C4369104B9D3B06490D1244 +C41D6085C85F1106082EC9DB84586230511C05C82412D2CDF3DAFBF4759A775628878F997415296B +C416AC8352A6C6988691FCB831CF95C10BAE691ADB3BA2918B35924BD5C3ACAD8B137397B10AF82B +479800FE16D472CD0CDBDAAB4F882A0649CF561004B8CB7CA32EC129D0A415BE6CB91DA2B65F44E8 +0D138808A127E851A7FCF927E99DAA0EA2D626B77A16C72E37F058A3B882FC4955DC8CB6312434BD +3BCED75780B13590BF4FE8D64ACF0371F9FB1D361B05025852AAB9EDA1A0C997CFA58052C454FD45 +1E6C1F194F4D363114E312F6DC35BBAF357A32CD200A3DD9654155134259887D677ACC44F89AA401 +CA27282DF7DC3F2F04A108CBEF2558DCCE28BAC2D87B8D5B7181EA927F61977764F882626D4AB338 +D95C9477C54E9C36012A3CFFBE199EC8120A99D2D70A21F9D9A0354E4EAC7947990E8A6E0601796A +AF6F14E758CABCABDFBD8204A8E748A3E5FEBA570D36E2BF474C0083229A63F96114182321B2EBE1 +BC76DD193724C4588C1D39D184C332FAEAF4C629F2B3B2F49996E46AA6C9F497428BEA52D58876B0 +DC07B460248BC85CC16773A5DAC36CDE8B152D96057F4EFAAF8B1DC10022038577368057699B3A37 +178A9F1F6C6CC60BAE820B7ADD0717911BD23A6DCDADAFA32473491AA80CFE90F2A77E24CE2826FF +77B18B869C33FA292FE01D6477765044C7D14A548B28B1360125C6933F05C58B0889390537CDD16F +8E967E0B38579449DFC1E07389B7069AA8594C5103465D5041CC929268DE863FADB6925B350AA94A +27D421FB7FCC81C6B35F906F12246B7A5140511A97211BA9BD6831A508E963FE8BE961332F557808 +488F06EAD75E86D60DE3FA2425AE8439ECB9112BC3E4D73747C1C8E87A649919827049832DB0BF6D +A8C85C9A2592AC002809070900ECAD52A56F1BFD456AFE066509694EAC075788456B0B0BDD7C192D +321E9FB6AADCAEF00F570F22CD4A5322FBCE8FA98FAEB681940895426270BB4319C11DA67D88552A +7373398AEC5DA7C9CAA9F3B34581C6E968DAAAB2751CC012199DD897B448986CFFBAE4D412BF9ECB +F46742715A9569932516259D3B3A5431CD7028E42FC751C434E2B714C718202BF02CAF9B8A2075DE +922322EA7CFA605C8376FA958B8FBE43031E1026FBE6126A3775F643EA67EBBD97F239FB3C435526 +75CD08B19CA5EBF53B40D728556B4481C7F73EC71CAB0F89E34D60C69B272FADC22E8E7BDC6210DB +09FDD913E209F49FD28E8712B8508904620250746CA3B21B026EDAE60A2822F59E912E626B93E0D2 +BFB3230DFD0E54E91A1DBA25A609B64D41ABD897A5D21764C351E85F9E87BEAB9E645149AD32AEEB +B3B1161032C701647115F98C1C2AAECE871862D91D321AB90F3E923B1FDEE00D927F897AA9812373 +6536E2E0700F10053D7E6C589BF66029D794883EAE4C8228941CE96565B50D48887B5314A2E55379 +59638222A6CA54C77CBABD460DAC11B063519AE4F50D93DE41763BA7CFBF4C7724360E750478EB62 +8921DAA065858341958E4F3EB5966C6DD77C05EEECDF4B5F6CF19AB507589B4219377959BD258EC9 +21C34FE1DB003F7D0FEA3E2FD6F5DDB0A2D62CA5A2CD3C7AB457DFF25094EFE04A9E1B9CE7AE3F30 +026B1CB039228D309A22899F6E9B9BFF922E117123347967D7C62C670E2C74579C35989925603022 +C17B1DCE378031ABC9B4B437C7B6E64620932E93189754C01D4B280B8B08699B2CA953AE4823BB9E +E34133C5C95B3290E1BF010705AD852C72BE87291E1034B09F44A95B6A2F83FEE8841DCF661770AF +44D0AC7F9CDB280939FC5D953D525E0B41B7BE188D5C794687330CD770D24D9CD53B895A253004E1 +8A31BE4E82B384 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndResource +%%BeginResource: font NimbusMonL-Regu +%!PS-AdobeFont-1.0: NimbusMonL-Regu 1.05 +%%CreationDate: Wed Dec 22 1999 +% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development +% (URW)++,Copyright 1999 by (URW)++ Design & Development +% See the file PUBLIC (Aladdin Free Public License) for license conditions. +% As a special exception, permission is granted to include this font +% program in a Postscript or PDF file that consists of a document that +% contains text to be displayed or printed using this font, regardless +% of the conditions or license applying to the document itself. +12 dict begin +/FontInfo 10 dict dup begin +/version (1.05) readonly def +/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def +/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def +/FullName (Nimbus Mono L Regular) readonly def +/FamilyName (Nimbus Mono L) readonly def +/Weight (Regular) readonly def +/ItalicAngle 0.0 def +/isFixedPitch false def +/UnderlinePosition -100 def +/UnderlineThickness 50 def +end readonly def +/FontName /NimbusMonL-Regu def +/PaintType 0 def +/WMode 0 def +/FontBBox {-12 -237 650 811} readonly def +/FontType 1 def +/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def +/Encoding StandardEncoding def +/UniqueID 5020945 def +currentdict end +currentfile eexec +E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89 +699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641 +2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2 +5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF +9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A2261C63C769D2F4B60FA2C438AD7D199D8E4 +5F7E7C9A605C8CA14E21FCD81C9A515FB8DB6F99604534D06EA9D87FE0FAA852899C9D0595C7A97E +6C55F79FAC45CD38E87B10D210CE7501E88C8FCD3444354365FB893A12F596AE2C1E70D5819EE0D0 +87D10BF8DA96F3DABD5405D28C4228C6C31BA4052464859640933FEEFD8071C0C84CDD829A9B1D0B +A01F25A4D50EE2EA2B45160CA6333B2D2800306ED2BEFDFE155E9D9F9342EB8D5B0ADBF2460CCC98 +643FB1287CCD28ABA7B5CAB92EC39EE2E918990372B16F8487EBA30EAE88708B6CF33B6C015D8096 +C7CFE2F139F52052E3925C0D50FD64CE68236D59CB83EF56BFC584150EC38065059F3308AD6F9A99 +F83EF4E6CB13855C8175E31417D190D036B387D3952344A950F4D8C7781B307A094DF1ECAEE4D2C2 +FD747BC6F7F9C6BD0E90C19294F96C8C5CFE88FB34C477574A1B1630B8CC591529E59B20794DA32E +61DECDA8ABBD1AE956CF74012AA01D42EE01E861B0AA6897C864788AE59DEF43C493246FDB1ACA55 +4C12594BC7B33657A9ECC9E3D1472EF826073F632BE540C35FF6FB40566773F3BB2204D3A579A08C +CBC844C14B18C350F003B9DA23A570C362D6003893CA32F86F59B829C78EE3188B6E3F7FA81D7F62 +2825C639638DFB78B7AF1F500F5B450FA54DBFA5CBA277C794ECE93275A3DE0B452FDC8DDC2993BA +A42F28A636008CDCB03EBF71BDCAF35019778993443F88412AD2AD0D7155A3944606463266322DBC +0244B07DA1E9C27A27B59664E8566D7A54CC03E995AAD008B0A17E2C3EF61F720CE7F7788599C4E4 +4C709CD5C31B11107F16AD70B17B9AFE2E8CD922A7428DAC171427FFAF51067307FAB0ADB530E701 +FD22DA22C4CD3064067BD4F6089C4B2C87937DD426E4E9D2F60E608288BAC9056554D04947E69200 +61E379CF5E81BFD32FD37EFAC1F61CEBEE551B0851516471A7472C60DF89DAA9EB1DC5A67E479745 +3E69B9E22BAF4E3CCA4192D603295B018C4AB69D18DE52DFDF15E96B557F290A4B8C5B1E7A6CACA8 +1F2351B97ADFC36995ABA43803A6E5AC04A3C93495F6D38106B8B144449C07D1358210F9176E1565 +72363CFBDE576BFDF99FA329DD1346E83F79E06CF68250CA57A68931BC7F342AD295D0CBA17AA95B +B8EEB53EA6E8E660B814E9F857CECB14F44A43288B69A9E7908D55BF19E844359879D28CAEF1C38A +36420185D20DFB32C2E002202800E8EF3D67C5D50E919657CA958B538D537D503444865331D79BFC +40312068D72364503BD0CC84B5F30A74D8B5B6A26AF2DB764564FB65A6BA8F9051AE2B4EA458D46A +4569F30C6E77DC097356770362E6CF3F1661074778EBB44FF7D1E3B64FF75E77E11FE525BB121C65 +46CFD13300CA1F02D571B82A5825E6226D14FDCF27F06D87452A8B6C5DCA658535CEE2A795E58137 +D48E566B69D53A0C3B766E84C51EAA221C46999CC8065ADB2F129D5B630FAB1814C0C33B5AEA0EFB +B6E994D80941B53079AF96D90A0B924F9B0E319BED9836B8F9053F868363D3CA554CBB181863301F +8CB940872ED5FA7BD18CE39218B5AD8AC57D0F752D941076B1C64D99BE0DB86D7A6D96510D772EB2 +4C587F11779BD21CFE5BDE1F29C1EF9022B2B8BCD7F91153C845906722477829C40111D810480F3C +F62DE8DBA7FD86CD236E656618CAF6FC46827FBC4898EA7672F8C9971AFE43E0E01EC8B77D4AF48C +BF1210E98C1DB15C16D149BFF58AB0270CF015B107A3A50F5DC8F37FFB92EEC8CB6778DDB7CE4AAB +C464C4AFF654223006A550EB52485A23D2B4AA7198D3CD54418102F1E9A4FBDE37B841E56F5C2C53 +966DB9B66B000E4588282E3FB80C2C519339F0002D2F83C979EDC5827A3B3C8EF8810A0F9DACB6B9 +998E9AF6551F56313DC4011904CB979AA2D32B11A811BC248141E4B9734D9FB7982A5671002D8279 +CAB93ABE057474628DEFC95D43890DB1ED34CFA8A20BDC3D874E7679A396158E522ED0AB969A4E3E +C7E4474E192590504D54DEB7B260B7935C4E56548A7D121AC1F741F8CDF259EA1B5813175A77A1D2 +D30BA26F65EB765A04C09ED51F69F41551ADF399E6AA2FC09788137BEA4913F17B8EB838C38FB272 +1FDCB55FD65697FF0B850E7D3D1CE266BF90F7EC06A9A0876BDFE767D3A918B092FC78C775F945CF +1F96E859C03DBF630D9A940939654C3549D8F7921CB94EE23D5A0535DE9DF31EA0F937F860B4F220 +A99ADDFC343D7CF7BFA0B803C12C26403F0DCFFC8EA786D0D8A8D9C367419CA8AE41190CE93A8086 +583A1E6C9D70B612C84D87D2EEAA71EC2DC12F4CDE6A821303D5F6A9BBDB7EEDCD289E80FA3B75F4 +7F481B50719DCF4A142069393593B9AF9CCEEAEC56A35B8787193D7C88113E9E1E221D151E093B01 +9EF89F6118BEC4735103CC8003CC5AD1B6727B3226CD44C497DA7052DD681695DBEC3397F9598C91 +77701C73BF0594CE93F23D50EC5BEE2FB9DA1FC966DF148B27B28EE3C89526DD6625E2887F9FA076 +7C127C609EE315626BC14D274FBEA56528DC06A27B2D476D46E9E7916590B156A5DF04A6CB15E362 +45D77021767B6E5BDFCC679670263FD891446C3371B11BB6E1DF60F960AAB4149D7753E6A5C33810 +C42C8BFF4E935003388506F8278BD7CB672F132E065AE684DCA0B9064D01DD620E7FFDFE04F14277 +EFE8E60159BA0FCA3FE2F28B902D4AC275D19F0AC6971EBE827C4A232D87650D2688345BCA78F879 +077114F0463C5F058107B669566F8171E4E284D278405580F04BFFC9902784216E0C9A17AA9B2935 +E66E18A783F723BE044389B7E9D62AA36818FF2EA406C3C1A9D2F3436F3EE7DB8BE86AFA8DAA6A4B +1B84611350D8D27605509612B515E16AA843164D5D0805E36A2B9EF74C5F6A0B9D59A04B55697123 +27F4B1B30E9587CD103337639967CBDC655AA46E80D2CFD24BEB50815B5338E522B3A7AFE8362AB4 +F05D8BC52BBA9C5089ADA8C89529B0275AF422EB540D31A938B8740860756325B966B36817115213 +FAAF92DE63F6BAE1E0064BFBC5588098B61EB83C71F1C2082436D37DAF1ACBE186FEDC4BE7C1233B +6F18BEC5F99002D21CB7864E4811F7AB3C03003E1E4490AD1AC793BD28FCD5EF0E6CC30EF39A08C5 +2F71939B0CEF620DC69E31E39D6DB969049031B0C92EF2DB653D97F370141456A52985076B268652 +FA2648C792780BAD637C4D7581FB2D62011D57E293719487CF2D1F013CFAA532E1C2D39178D51272 +A6AF041440BCA174B5CC902BD7390C7D3695056CB4BD7791F9FB6D88E7A70DEF2C97869F5DBC5BD8 +23C517C7B7C39D624DF627DC9653EA5347BFDA80B723F05F6DBB4C9EA501D862ACE05B9DBDF21B70 +56FBCD8C6D4B85873DCEE6166C8B5ADC0316CA12D9639F361B15A42F00E1D62EDBCA1111972FA0F4 +5758BECB31DB38316F3CDFE1B41748C93ED58B67E9B57ABBED5924A6D53E99FBC9A994A6489A8BDF +13EB685548B4DC6D62DA7426C22227D4D43B6FFC7B5EA91C896730253E8941AFEE588359C2BECF6F +FC415B9EB6D31CCB0F6C7F85853E6449FA6D627A97A3CE8303F148393ADCCCDFA2FE085C6908BE5C +3C05AF00A6F02840206C3253A559AC5C049BDDFD11AD9B118403B84DA10AE3C470CB9A9A2D1D7B73 +2F59F5FE146DEDA60AE750F551AAC934621B4470E1BC324C436303E25F81D0DC3188BE0D6FEC5414 +C20E4CB18952E12CB6423DF7124627ACDE145500D77A97A8BFD9CB50D1FAA008E2CE2B2505A4749F +1EBBB092C347023714055A9B63353AF9E7FEE05BB54C9843698101F79888A91531773830C2C967B5 +88D3ACD2192883D5CE3962D51084FC653EAE2C5FB2DA41DACEFB5C76812D2EDB5B109677289CD199 +8D457FB1023A19AC67295BBC1A9A20A426B06A368DF3C5DD083CB1180D287F5500F2C635EDE157EE +FCEEC5503447382D15C748C1E35F68753992E5C90F900DE54D18F8E1B355D1076ADFB1F3590135FA +D1A36F028E44F48ABB149B80CA9A54614D467F8D71CB310BBC7AC7100261092DB8C5BFD39E0AC6BC +2C9D6CBC3A8C05FF8A74CB21608EC4A4CFE4CBAA2D056DBA14206106044DECF59F957EF8A9CADE4C +9B19D8D30DD4FDE6A9548E50DB51ACA73330142153FC36B69C1C8D5B26D0C689B7040E81AC2C864F +D7C097C99BE5953843E172C97AB5684F35FB03A725A89DBF371F08DDF40A1531FC1B676DB0E1543A +EC6E97D3D2E4AA3D5831D8B3C952ABBFA112352814FB6FAB61A0D680E6640F6AEC8426200CF61286 +F7422CB2F78C61EBAA36D47EC16D7FAF8B4AF31D090CDFA255D9D7C61D46CFB22A7D6E1758E71ED5 +67E00CBD8E8F468DDFB477F091A2F915627F22FF47B876544BC1F03B6BBB98385F009C20BB1AA2A7 +A78674692B8EAC2E3C8069B79E679338DA57F72976810F845BEB6B9ADD32B95D78E5E60F16DD1668 +9C05FD82D36A3115BE8ED494A74DD211D58A2CDF983FCB9CDC29BF7F0E29988FA23560EDF514BC1D +183F3B2A22C09FB179B47E05ADEF48DF02F31C29875D1915037B19407764A4292FE44E741651A8E3 +BEB5F0D972B6327090F664417C84F84FFBF0AFFF8B1D85C822D90730AB4140C42A51AA8B1DBE4398 +4EA8566040EB8B341CCE23FD3F69DD235A080BA5C69AECB9BC732BC2D7D40617DDA6B79FB6EE40C3 +556C7DF9B23DAD89E94054B1345DB8402AE679FC4655A4A776C0150463F8DB2BFC0608EA1F124E22 +1DDAE6026B5E5D007A7E4A0D6B3B0CF3A2669E67C5E4F01551966A7BC48F2F4B6A87E740D8095E63 +F77C7A027F26B52F2299DE5B8A2F6209BCF3D31CB0235F998F781E5CC81E31DC424E008D46EC0920 +2951E5684804A0592EA47D6C788A20487BEA2EC8F2E6C1D7F378B62DB43CA43C4B366F8B4319631C +FE9854F0E10321CFA3B01C873584863BBEFC23C72C05E695B56E8A52E89AA2DAB543834D34DCAC5F +ED08DC51825C5257AE59850D101D84F4CAA1D29FC932F9E0EFFBF7A9A7F3685F61F0490CD3CC8988 +2DB52A757A6AF4C4E67B407BD2316B1C0FFE7DC54E43C87B874F57E4903334E2140B011484863CDC +ACA331175F2CF3D72E0042855983AAF8853D3015E870FF0807014C31D55060DF3FE1FCE157324481 +2744AB51322444632F9AFDA6706E320FFE82B8CBE242A19DF00CE73EE48E25FF49D5871BD3E60652 +298FE3E8D400609E232E0DDC794C0579ACEF89E841B2EDCA50D51151F65E8C1CC3B01EF1870558F0 +BF5743718C3E068617E81BFE120C6CA16E0924BFC2541177D53671CAA3AB641C41557DCDAE1A3461 +47B5E999C4541B08B4AFCBC187AFD653D5B5F8386DF6AD8FE69E21BD0567DF494F736C6A184FA4DE +48DC9F347787CA96E2E00A296C2DA05C2AD9BC423E9CA428D7F1FA12DC9353A302FB8C529AF8688C +BB543B45B2717EBF8F6C497935F4F3BFFD285E0402AB7544B3CA4643AE5A8B5250ED987A95FC1F27 +5B9707ACD0641BD0EE2AE9758494F8D8A51DCE408A38AC20EAF0852D72D84D0C6BE973326793AEB9 +55EAC6FE0A2813A355DCD22F6F2CE56588D1C055CDDFA98878BCEB6A018DB22922D2B600A20F8184 +2E665DF41013CA0947C4237C2BD60A75E2FD1A3FB8C8FA19485730B87461AD466ACB02DF8CA24091 +4FB090B3D2B41EB6B8FF05E1A59D9FD668AF70BA5BB72778953BA55FC5F9F626043450E1D09BC83D +8605098ABEF884639A37809A32565CBEFB3FF39EE53D6C18C58C272BB928E4410E361E59A50F242D +69747A032617C52DEBBF62364AB5A96EFAF642D9D82BA679B1D70FAC10A4EB62FA5CFC308E86368A +AAD7E75948F43598CD1C544A0D4091374D7E88D4522CBE902391641327E888E7748FA889DCE67ADE +61699E7D77763681CAEE9B1CA8837B2F7EF9C18CBCC538C465C8E2DD34616953CCB6030A222C728B +834911C1A179E2C770289407AB28B303E724D97F747D6134B425216A64C6E0B60F633E2B85300047 +E4C90339CE030A0FAE31E830C8ABA5AB3386A3B69267351A7BFDD66356AE5E57FB2994452993E90D +E7C4E260ABAB93C37831856A650D56E44172FECA01D6C7C380F250B82473960D2A2A5FB6B4DA668F +46E624ACF7FA0FD4490F485D640A3ADFC9F8652E7A38CE5799F770C3606DB4B8B947F93967F779E3 +A3C0572F13A5A187D31D7BD12A5C7BE23CB6ED6192086241B76C5BA6983DB9C93E4B208D707D3760 +F03CD6272EF3A4CE89B8E52E6AC5871A3D03EB975759AB4BE239E5EC7842CBB333E692CC607C722E +185D3C39164DD320C6945629C70FF66A5237C0A9520A1FAD6EB9816069351AB0F135D90CC0982B14 +7D2294AE4A38A527EE40BE9CDE2512AAEBB590E134388BB171D0956A7C4566D65A9A041BE6C4F883 +6B3EC3D2ED1B48B566A783292B15B6127920D247D494F070BB20BEFF60640B11B276DDEEE49706E8 +B2B21BB40B7F00AAFC594C492C25DCA774E0B80D82E927448DE2E74A9D0DC7AC9260096EAF187B6C +D6AEAA6D1DC4205B4411122751A5B22688404EA7C5861730371FFAC10F5AFD4727A0E402AB5EA757 +606B75EB86A05E8F774D6E430A1A3FE2A37EBB06700474239FB1CFA05EE44B91B82244C575B52E7F +AF934B04EEB0D933FEB57EBE326D75821C8B23EAA85B583AED4320B7F04B9F2DC591091216FDE52E +064BAAA9C2C9D9714B95A4558C21F3CEBE624B5403B31508F178581AF6863083ED762F1E2E34A45C +FDD71660D626FF8648F5D6C5E580D4765A67FB6159EC8077A9F0A88038C8D3D7C77FF0926E2123BE +874F7BCAF129D55A5B5960F824BD1728ABCFCC51D23936DE9A25C408D786E44C3A2BAFA4423177AD +060D21D38E15E23EB6FFC0B4120E814695D423EEFC2744A1FC81B4DF89D76F0A6803D8B14E75538C +AAD03A72517B86514F6952F6FD619D9E910D980F00964DB325318C045BDF79647F453D4A5CF4E61D +D5359782827229310405FBCF6107C3AD9DDEF9A9A339D5D5A6EB2E7838A0A43221BD62CBDF732DB0 +A638A52016FB35BA7761AEC846A023D3BF2D1BB183543E81EB7CAC1E5970CDC6F068C5EA118C7AAE +528D1396E6DC939112DA4460C890EAD5C01BDC438F5BB734218BA6270ADD0DC1778FD8AB16831D6A +302B814A1A44B07EDC65956C9E6CF4875DF521F3CE5B422F71081B6D69BD270F739095C9E81C0377 +934A8BC6390C420C4E4CDD9CF7E32544C68D884E15ACA3BCC07FC8C132D8FB9D752C15D75C52C288 +57E2EA461A6FCAD90C56843513F74461F18D7164BC597A28AE4BA7C86EE1703535A9B9ED50122627 +71FC12F102E800E0E1AF7BB46681BD2B14B614CEA91B7B2AAA35235DE76C0E113C92688F8EC81277 +D58C3406778E1EC1CC15F1CD9A137C8FFDAAB99ACE3BFC782916F1A877170589A92DC921E6740A22 +B84DC6BACDABCC76E64C79E3A588D80F8F4D376E1B426F15751CF7391102102F0AFAFD8B22DFDEB5 +48AEB5F30B1673023D22054A13391A0EC08DE6E7B685A0D031AABF20B7C62187C0284892D5EAADF1 +21BA28263EB863D5E36EA9C06A77CCFC0E17F593961591F84D82AF823EFE41044C8D606FEF83CCC7 +B0E961E7994DF8A3CC36B209D953E250ADAB8D22D7F2B4E2C9CA39EFA2D93E56195C1560E30A5190 +CC5B17FAEFCF250DF79F6B624A4B917E11C332222FCCFEC4F6A47BD9E75DA9854FC3F7AE554E91ED +DE144D7AEF38A0E3EDB5E5A5626374DB94F022C8CF549093041DE00D7269B7CE544E748439BA2870 +718C08E58FB4A77D93EBC04B7957D272AE1601D41BF85A2BADAA0DF73B0D3841D4839C85677FB2E1 +5F1D6CE592669FF4BBC9C69DBA334DC37706F2F6BE83D5863E8CD6A30C08640AAC4C233684E66B4F +E6B62D4A8BE9D531E47BEF5640D9B5C27D990092BE1597F6995C8A77BE9C18AAE6C1CF130775DDAC +41D34438FC7AD8E042CB56CBF2944932EBA7D053E9376FF398367450E35A1945FE23E05C921096A1 +5454721FFD0F429A3E06DC3ED36F1C170BE79C66996EF8337AFF85B90C5D3A4A94455AE9FA32E211 +7A63E59001F052D5F6223125BFAFA40901E98960ADF7BB886729DCA82FC3B8CC52B37FF2517299E1 +D769057F8154FB95582F02CB0BECC873A9C71796ADBD3E91324FAA94F2C41CF57C30B5897D031C02 +D256C909E080E70BFD1F32E69EF67031138C2DDCD1A8E4B65E485C23C3E450ABDD9815512D6F34A8 +4B9DB715DB2C7A93BFB424316E1AA44397749CB01088428F149A3B4324737ED9957FD388248462AC +1B2610D72BF5C073ECA567E7385CC959E37CAC7E05470160FFA5A9F63B8E9B082937E911586EA165 +374938F492EDF28CE6020953A5B5CCEC7737F9D9CC8538C4339567AAED3794ABA3B9F4EAE65466E8 +E326F6C399B36355935FBDCB9972F10B13494DC25097FCEC5A6398F275C8C151558E74C5175F7BAF +4155E36B733F75CF9D5C5979B0764F14D8306E06BA24BF791141E404C69F3F8FCCD91B9C58C2C671 +AAE7D4F9E5D6414E46ED633A5F78AA5BF04E652246A066EAD9E582B181CC196EA2D3CFAA383B5D0E +4CAC9336E119C08CC6AC55CBFBAE147C623B400453BBF447E96DE036FC025624384359EED7C7D5F7 +858DC0521377CF647A157FC3F188DE5EEF094DBA125510FDE34C570D7BE76AB5DF0A28BF45DDAADB +EA7EEEDB936332DFE93081E0AFD3FDD46BED08D6914B2EFCFDC41662A33B90B03D76D34F48D30FC6 +BBBB600E90E6AC7243FDF026762A44B4D6E4ECBEF48C9D7B696AF29EEE063E557D8FCF0F09E0136F +45D17E608DA36E59F2AECF8493F8D62536119B5F7E1554DFE3F6E8D7C9A2C6F557D18B4AF92C9F6E +050975C3B5C54F9B5F4E39D600B6FA2CD6DE203A174028CBB2A201AF126D1013C229BB82CFD013ED +199D01E51EE2780FE896E01C63C655087A3E61A7F1029FA5E97EA1872F1B45F22282DDC317E17926 +7368CB52DA9444F6055A3C653659CAD2A1D8712BC2B1B32C1DC6906D957FB88524EE066156ED6BDE +B8D832F9338F9912E29A250A8C4674E667C1C278B677AEC9972BE83CBA3FB779893FCB8F81A323AC +91474BA2A2334A07BB5628E905C518E634F6761A3289056F83D5DD7B3890987EEE1C18FB2D379CC1 +905F1AEB3B3D2AD578F0D6C845D2D40C4BCEE3F71C90E68E5417BB8CDDD878D83BA80AD8485F4067 +E5C3CABF28AB56CBB219C0AAB8FFC6C7E192BEC8CBCA1459AE4450AFCC81B9548F40CE2622E5A7C2 +81F74DCC02DAD57EFD92D072318DDF05BF42F1EA8163071E23949B0179CF7DE64677CA99B23CB926 +B3E294194EC13397EA1DC9A5E1CDCD828156CD71F81B64167D4FB01E6002713BD8AC6F82B20CD369 +9C6CA4704DC5C65A2D66EB155B7AF1C9BB46469416FB49C1C7E17A30A5F045271D7DF3FFF2F42C6B +470701C381E3456A500C6BB3D0E47B4D91C5F34B49BB6272F1F8698B307D89EDA3A1565DAD1C0864 +627560CF922DCF5B34C67860352390B282F95394AA2CDE0E97CE3ED39546A6AF1C52BFCF81A29BE8 +2C47C99E8050E4889E4575B75F39E662F2DB7420673797E2ED3D67CDA7AE2C15D0A0A794D57D168E +BE13214E89E0209AB2C0EB7784E9491AEFA3C02D0DF3AE5365A0FC4AE023CAB528162C7A1B173664 +9DFADDACA8DA5FA18B7D6489E4229E9E24D38A620464A744A5C60F6F9D334B908706B738AED18669 +8A8B278341FA4D65A0A88680BA484694921512F7DE93337FC1C02BBE6E64AF2DAD07603279D87329 +1D1F4D39C1DD6D89C90F65240F4808F6F1115CA55B88E242565E59F3BBF1F10EC7B88872E9AE61D4 +4CAE185463EDFAF7DF63DE4D2207D307AFB61501892965170D2945846FCF5973A1D458607F50C15E +06E5BEC715E0C156259AAA6C735593E5564F65F443B78CC7512EC35A56F126DF9D30974A40872E42 +65E1AE5FD483CFCBBBA26DEE426CDC4721F19C3FDA86ED7AD4FA1120F63669BEFE7002B128CEAFD8 +C63E8AC09943B6CBDFB3D2476A026C00A8FF81B1F651B97F310C82ABA5F388CC1DB5AFCFF5996D52 +52A6A42FA4D972E41EE56088F78CB966F9051171C472C774879AECFFF08BFD9CEA40D7C298922ACE +64F28C14E0B81F4DCADE81D71DE3983D87D905192EF13CEE71B2D3FF1A88AEC671EC318917DF98A3 +C9054E372D22A3CEC82FCC217F47319A40900312F6E32B536B9E7A7FA0837EC65CCDB5FB0D414371 +17596CB39D9382262DE6E65379D3A9709B2CFBABF5FC5D5B352425F06F88CD31012A2A4147B112F0 +C1C0ACCC808CD625E0228EEF66661F70AF96D3DCFECD402700E4F6522AC9A856DA466D55C84F65BE +2810A1565163872D62EB81333A698ED7B68352CACCA2D7AD38AB55C19E4F5582F75818302F5FDADF +1DCED09D94872F2D48FB636C8E38C7563C72C771A08C6B1F041F3532BDB39006C89A33C09BE1E3E6 +03622D891F98010BF1DE5355F557A1E09448D486ADEF565705277B31B8BF2B86761E32631E3435B6 +88B79D566F1747BA456DDB43CD239FB47FF7B425EAA4C657C8EEC26EE01AED07CF916E77D53634C1 +37AEEA009C6B515B6342C54BE2C7B95955B1A9DA277A0ABCDA2346E88018C726F481F71D6011AA42 +F8852F2E5749518FE3B3AB668213FE1A05C10A1C53953D75312631D6BBBA01D418199DFEFF8CF548 +6109B099FE8E2F606165FE30F532C03567785D5362AA873C9D3EECEB20F1945D55F49B0CCAC84967 +59FCC7292E46938943C262D78F3212D3F9D0F7B103157F423D71B1ED54B2A603F4C269029918F238 +EC6828FFCEC66009DB9C9E59534EABB183F31D7AD4C57B1BDF0BD2CE5A421882BC10CC1BCE6A970E +2B586BB221567CCA483989DD0B8DEC424C1D1FF042DCB7834423CF244EDA28D2D969B17440CAEAF0 +24A6119DB010CE366821AFA424D1B8299609C04148275AE6E5257A7ACB3C766C747CE99CBA2D703C +F19B7CF301B634D8B613DDC4AFE4633A4D77BFF8E00CFB5E289EBBCAC90A24307E7941EC1685CBAE +400CADD876FCEF7F6557EEE167D2035A05120293527700DC510B038A496BE1D5CBAEF24ED39F7421 +1A93AADF22214ED606A80582485AFE358E3A46D0671148998A3B3BE209467009B43400870359D418 +9A8CEB4D5866AB52D16D9CEB1EAB71C07E6CAA34B70E3096BF7604C22C40D5FBFEEA616DA3BABD59 +DCDB97D883FC8742B8267A16A99B7953225F7144568D566E64542C92E538AC140C851E5D295528EB +7CBB49909B1CAF6409C9BCCEB325468FA0B5F7CB2987382616B477CCFE4F4AC79E4A6F7165363543 +F04DE5B6F6E1C2E910CDC3CDD6C4C92737198F892337DCB6647BD226C820AC99C65D8E7772BBB74F +E65DCAA8A22C33BC168BF48E40A82700A3A7668C5A9A71E397ACDFEE7D556C5C19467B7AA69C260B +727407AC837BDB7D67DEC055C1F45D8BAC61048C45BC9FB3CEFE7549EAA2992D2EDC126FF7A05EAE +58613332A2BC1465B2BC0429162B907D65F793D236EDDD8D35405866D71B25F62DC4A7E06D4DEE82 +840ACCAABC0774F8A63E9C0F7FC980B3583E7A8B01C46590E3BC04EBA565C2EA94F057D964A78A90 +EA9F52ABFD70F84E44E434BD10A42E98C794065724341F907E35D3CB257161E01C7084E3A0166D15 +CED65DA7BA87DBB2EA33D39BD99AFB93D3548358D08330E807F8552CECF63C84F805205491BA3A1A +622E70C232FADF3BF2DCFD6F0539158D3306506F150B0518371912A25EB96163D73E9EEED42EDC84 +D688BC7F7708D9DCA348FAB4DF62E5809BD094842D0A31DBB7C4B41F94D946810C5EC10B69AABC2C +91A59500B2E5D37F4755DDFB7AE4ABF757F4C5BCF77C7F95E6A616646456FE8F18407080BCABBFA5 +7704287AD26222DF91AB2613951E2D679472F8ADF06EA2A20205EC19972299A78BAC52114334470C +5F5890C2F846B4C6042D73945127F2E3910ECA1C4CD7A16EFE4B4BE38A15AAA710682C3836A8CA83 +FD384970139D8B46FB0AEBB002DD224199672FFA02250FBCFA4E649E335428FC71F50F45E498419E +DB0E970F46894A48F65580881C9C4250FCEF65C9B28699408E18B26FE6DB7F1CBDB767564E73CB59 +54C6D639CE33220C894F36E70F71C9F9AA3FE2AE0AA0E3F2E304EC5ABC661675CDE2E70519E4220A +E26FBACBD01D5169EB844750753E6CED53E3678FDCD08AB93E10067E9C64F38B40B76D99B6CD92BD +F4155A1EA5CC824998B59AAD06E09E5F15EBB2288D66EA71B296616734FEF2796F07FF0D8B047074 +A1111D68B99C2B70FC56E74A51B062F4998ACC85B1943C9477E436E5CD7AB18DBC898D21BB93475A +623BDDA71D7B895BA2D4C10F4B90BF335126F4FD57D73AFA50170F6B3C364922E551D40E35DA75FA +891762FA23401D39260F2E92C7807C746F13BB35CEF9DBF2E76E66A72FEFF095DA482A4DE8A42091 +7065736CF4DE904FB52E649A32255E2030A7B31B686353492F31C064A3C4B0448C4BFD44B8E15384 +FD809B8761EE26A7DFA1758D57CE4F0BC376EB2B3833534B15A83436BA553955ACB5A7A66796AC5B +92DB5388BC53EFA27508B08E82821E5CF669BCE52BB860780F749B4F38ACDF5FF12726BF3EC2743F +01014CDE96FE6B4C40A034E9EAFCA2A35CCC776C2669E6AD138070A40F48ED79136D7FF57E993E09 +B81C543FBADD350FF5B5F7A46F060F88E30FE2D8233832D18B6C323EE017EBC1DF5C838321CDC8A8 +4CABCAB20B60A1A3AA028F36EA6E87C850AF8AF7CD50AA6359038BFA8818821D02CEE8F51DAB8C05 +F7AE9797814D97F3DB8CCDDE45B21DBB15CEE292FAA534A5F317B357F4091F3DA357325B8B9F5EDB +45865415973C143E5E5BAA483FBF2D06CDD4246675EC58B84C6AE65CA743117FF00F229243772561 +31A7F2BA26A9115AFD96C18216CFDF41B7220ED0CB3FCC26C36380007B382A02AEAE428887DC8BE5 +FDD630AC57EE3DC156C7B8B29E687F24442E35CE10BA4087295A641F7139C831F7CCDA6CCEB5DAFE +537CC1A97C5A337D3C48A6AE947F58A30DC08CC7B58DBBB4737AD52783C573FC1E9408F55495A80E +7FDA61F0B9C4F090158F1A416249EBBA936C27BEFDEF19D1BFB839EB70576A010706D8B95657B218 +9C2AE04C11EF9E57FE09880273761FB4302C388BD608FA0C7F00F033C9C00F4E3D5CE2D903E0DA52 +E69C7745EE9FA75E2AD93DC6CB5CCFCD3782A699B807AFC36AD1F62B05856D5DFD6F88831B90EB3D +CD523582A49732E3FD7253126D39E8AFB8458B5F7AD7F94A8DAC13365F433C857AF4A42C0A08C4DB +9887C4957259ED22D13CFDF5995DA957EA5A0F620B0214FBFE08AB6D552DBF048D62CEF6EFF12F15 +3511ECA7833E0E3E95F85E6AC0F95438AC4C126E1F1ECF336ED31CCA7EB216D279877123FD9FCD8F +B5E52B587CFFC4428456DDCA816819A8A4A211D8F1629E5D42BA4C5C356E580C8A22C61D987552FA +A97893816DA73D423686E4EBD44375C257F031318865A20F22115E72BF1EB9F93AAA169C140A33A0 +6C35BD4526A38BE79CF40AD1EFA10411E8F3300A8A8B97AB140EE6734E1BEE6C8EE443D698D34159 +97649C6F10F20ACD80236422E215E146D744A262DA3FC88DC0D86FF66512F49D3F957D3C5CFFEB42 +4823509F33F155057A4C6F37B52F4667767BA94F6B8B62856B553F307E5D230C44CBFDC9A97A45B1 +39FFB2F2565EB0E22026972FAD0FB7B9576FB6F368B61979943A398773600E7EE1DFEFBF26D45D40 +BDA66EBB96A56EE9CAE0B2420C5DD83E24DBA9FF885BB844BF3D2BF93B07325DFF60C0CB5FDCCA0A +C8FB5A2E119D5AF26E53AB8E3B428481C2871DDA26EF0B621CD8572B3C664BC7AAC01A1D05B98F79 +1A7080D294BE81099BDA7982432F3DFF4775C44D23F4F1B2E0162B61A8B2CB5EE8564BF98E2ED403 +2219085FE6194C19DAC98A421826CAED7F1AB1477AB327506010217283894235D7DBFC1153D5ECC4 +8AA7293F19592B4D7E95FE55151889BCD1D7FA7DC2370D2DFE11D7E4EA34B5C7A8E73BD3A348FD38 +9EF45B6167FB90BA44C23E912F9A4F2FC0427ED070592F7110183BFDB2C400393BA7569058227926 +351F07FED4F33633BA03A72AA2DC6B598E49B96021DD868DAD0F352E5722FB714F667C15C68D49C0 +3D822D82677EDFE86FE9668E537DA284068C9B0AED83074C92A5B939296D505B837E6A9DDAB1AEAB +7455A08A114C2222B339284674B74BF4CA9EE0C020BF2A148B439C71C6BE51A94CB64FBE4A7EB295 +5A455047CF5CB348B062ED4F6471CBC3E9ADD9BE9B96879AC7BC71BCE02FD02F17C6063985A5E898 +3D205AA1489DA13C408990ABA1C54F2F501AA172F530480D789C848118C0A74EF98D5F607A067BAF +F6030D887AC6A6497F9A0B38F9705F328AAD4BFBB634F739386177B07F22D5771282444E5EE17335 +B4D0EC86117C697E79A5F4F65FDC08E4904DAEDAB20067EAE2448FD4301849E456D085F392DD1316 +7ADF75CCFDB723E2904A9C0C976D6B84DDEF9D92B0E15FB246C3ECC2D0BF314CFB957757B3A3E8E5 +801F520644E4601D291DA0F7507C06F3B9BB36FC1C70EAA444E14E56C0CFF06C7F853DF36DA9D8B6 +AF2544B853DFFF535A7E5C6FC145250CDDA229956019659D0D253A19A7B51A4E538BDC01F74D7704 +9949C2C97C7EC6392C2E61CCC0992B66DAF1AB08551063E53180D2A67DE496716CCBAA45462D9F91 +B66A22545962DDAB120511FF08627131B95E5DEEB8B4DD9643E7B2AF65C0FDCE11F5F1E8DD468DA1 +8D41C8C4F00EA73836F4F70EC50FC3EC6D358C0658A4261C6D15A582A2C7C994E7882E661855B352 +014576858A265FFBC425160669CE159D07EDAC04D060B44E5800A7AAE8E339C29B929AA81D2F515C +46229D2080D5917AB20AB6B34FDCA8E4AF64ED660A3173786FB1A1D005D575C2A5187D3F7CFDC94C +CC44A38C5CD523E9DA726D8EFA6DA7B6131DFF3435FEE838B2C7D6B97934295F06202D307FF78D90 +6699CB9C5BBB10D1D4DEA5FDA5BFB094E704607083B646D37F5DA1FC7AD21B813F44D8C1AFEAB666 +55AAA19703BEA2E77DF3BF350E17C74B3447A452235919452B5175570A006C7680AC05E8950A62E1 +1D7E3ACA35A397D1E19630D094A86807593C97F4C484E4E06BCFF708B6DCA972E3A0009E1CAC0EA4 +141530F5C1B8AEF5E1B933F37FDDBC4BE22B74FE346D1A3F5FEC0818F8E61765568A2AC04713E828 +F98C449D9A1CCE52D10D61DD8BFD084C8D099A75D89DEA64D5A7CC68BD5B0593D97953DADA976383 +F5015915618AEC56D71D1DCD55B89736395C609B315A3F1E1255432FDBD37F38CC43C354FB4B7C44 +F1A7318B0B7E99C3C08C33B953727B6A6328051783A0A33E3CD9E498346A3CA6A77B517096EDD52A +E443B87643A646C3A7BB97F742888D33F9B3127E61942F4103C1DBDCD8EAC8F9E259773066736CA6 +53CE57E8822651261D847C131321BB9D6626A1AC50D047C0BA47B411DF2A995545BD68EC0287CC9B +31D5DDCA8755EBEB10ACCB3903AB0FD5788E984220443B8459E7C078DA4289F1350905881AD6DFDE +C47302B0ACB0D4AF8CAED02B4B70DF3CF8FEC118F0FC2D3DDE3E494CD160E676E300BC464BD4400D +B50EE43B314E0517037BF971ACD7CD327CB2134893B8A0410E68DDC518F5DEC966C7884CF5FDFE74 +723177F20DEDC039D879056CAAB4BF045062D3904F615C5CFE109AC7A35599C94024B41019B9AFD4 +04A80ACAA4837929F5C9317680A13D157A03B59A5588DF79D2E113F5F51021D6F6F90E8BBBA2C252 +FD10651BE80BAFD59C53A3367BA3C28DB6EB9DABF1EA99F47B503F627E15DCF3FD645FC52C5D5D0F +2F07DB4C25C0D1E1C00146E1C4D973E613CCDBD3F9450CC0F5343D79F05E9492E86A1BB889ADF405 +03BD7F3E7543436859184A5B20BD8A172F350D846B7570803990ADAA48D4B9155A2B4C4BFBEF1E1A +065C08E03928559735BDD442FF1E83E1FA20A5DA57D8BDB2FF5427C034CF0128AF111E6E73099E04 +6E0C240E80A73D7BE72B87834E45898D475521CA3306707631F5C6136199F354632D1A085F12A1C7 +C473868B62E534D15F5484323E63D0574196A19EF175214EB35A90873EFCFB92D6CF68761D45E37E +AA61E1A1979A82009507CA193E44B36A806486665CEDBCF387053ACEAB979BD35D30978FC7659ABB +E844F4ECAB3303318ECE80777A5FA5A9DD91B3D06804C4B4E9B4EFCF07EB89866D0DD8CA390CFD15 +98651417114D78776B1A1D36B4BA17746D6BE7FC123D473EF1EFED1C3BC1D555F914536869FD5B0C +35F9C83F65B0E6BF7A627B9202D787D72C600DDB6BCCE613D88492E13CA0AAAB196E8A49928C62CE +A4FFE2D0208EDA334ACF47F20BD793124D2C5546C03F4A364369A76A0425262F9D9118AF54E37D32 +E33AB25DD533A49DF5FBF1BAF4CEAC2D9D378CDCD13B00FDA432D9042F623DA41AFB80699B5538A2 +5403B0B3EABEC9E8EFCF42FEF3EA9F91766902CD206B0787C187D5370B60AD6DCD002DE2DE8DCDC0 +B4719A797C5E26BAA67665016DA0D967FA1346F9588AEDA174CA001B31213617FE19EA218EC23597 +79D979E2663166489C06993230B0D07973A117C4E3F4A4C93CF8428248DD5389414D679C69644142 +67C7FEA17E35B0CEE456667A9B1875C81B2302BDDEA2818D6019FC1622A82051F60584ABC904CD91 +8676305DC03FFBCC64FDDAC8D8AA9CE2EA00D6C97BC63C8A617DEDFC0E40775649438E9F61AFD179 +5E3B20560B01BE5E0983F136CF48AB206954E41DEE0D9DDD953DFD01CAEB569151D6BC0DFEF29D70 +FAE3E198E7EDD8922C0E0BCB8BCCF1C016142C1A8B337AFA7A05A9D7534B184BF3BF827F371E9BD1 +9A71244ECA1BA73D484CD2FAD54DB2F0EEFBD54B536EBCB5094E6BC2F5B2AAE41F05B4B311115876 +ED42C34F8E643B53372E3F6350DB8A38445822EA9A33E27FB0CC42CEDCD1FE2FDF723FC47C996EE3 +56C402112F24D0AF899B2D00BEA1CFD427998BD22B2A09046D6737814448ACFB10D387547D7009FB +384AF0562C85694C071584236D0F1F3D3FCD0CFB38B77C81889061E668BA7AB37AA60F58A3967DE2 +6F939B79CBF10A9DCC42852561D8D6754F1B660D216AAB1E133FBAA321C56E2584BE5C9BAE20CCF0 +0E8DBE6D9C2FCEBEBAD945C3C04101D2387351F132628786F6D9D4CAB83419288D31F9BC600D9664 +12E6AA457CE6CAD26A4C0671097B98C2384C81DD8B9A3222D4F4BBDA7017895C3EDC26662779AEE7 +40D9D7E24185FB821970B0A3A94041A69E4805EC88EE1EE521981536F2844FB8F5EF645F67D42CE5 +148E2DDE43AD5AEF200EDB3A2C7866C98458A92666E5F9E070178BCC39F65A893102A10564AF4E8C +AAA5075D2F8CD7FAB0401C03AF299EA3515CC93066744EB5AF7CF0ED06675BF049A6E3C211A89E16 +DE5BF0445A7CCA6EE8EB0347454950485D884606651E5887FE8B24323E2AA16DE22FC1FC8C4F06A8 +2A1FDE5758976024068197E1F4506E4D3D8A16D40461A4586338B374A592DC60334402F76388AD6A +457DC3F54E6169CF7AE3959676E966A45609621055EC3AF80E182633300A4418E34A66DDFA6B569E +5A13C9115B5FD3EC1CEBE50FBA247F60803AA83976F00117536342DC3D9890C49B2AC701D370E43A +955118967827760F7091469C5406F08F18D7E3548148CF0E312B1DC71DF67A5E7A1656CF2F47F3AF +F3DD50FFC2FCDAB7177285B29C17CA43019F62AC6FBA52D1493ED7C427526470ACC8389BAE827759 +4958908F517B2863B83292EB5AB3F57FFFB08393CA610FB1FE905D88A0A16AC395E2A2A6DD033D6A +0D68992F830B2E1B95FE357BF672716E88FFB92FFC3D62945D1EAD22BC68C51EE0E10A43011DB94C +44685A5C4576F6EF44CBFB45F2A4BF110A01657DB51FD499767E78058199B31DFD60813F1A344F86 +289F9378231D5B151C92385E3650B4FEB1DC91018EAB8474CBF69FDC1496A4D078D2C351C8196451 +247A9DCF8117E5B637371D8E22E248C64D999015C3FD2311E9950B8EE0922FBDD3D7BFF766BFE9E7 +CE0BE12F318FF2A7B5A9C6D00A54401609304ED2C55F5C1EAC3D4B38355BBD85D66D61636FA6E30C +2E82829376BEC979A6FEEE040E452359768ECF90CC539A546F17AE906C76F14F86FF697797322B05 +1EB311A759FE260C1EEE5DACF383816AAF1294CFFA7BF87A4D9BC595EE8F2C2F86FEEE11AD959D86 +F22FDAF4CEC098942A57E57813A0FA99239E994FFF353C1E781D666B8928CFC648FCF0869FC68468 +BDBDA7D280DFAB8B0B3A4CA35B074B686DE8D372C61FB32305169A1A9912F6541DA16CD6316A6EA4 +51524757BE5CF6E820011BE3859FB8B8578C100FF029680E05F0E0BF11D33FE19460C85EA5E4C0EF +28E29407C8AE6BE01CFA0D5022BF9FB01416FFF722A784DFC8FCE330EC95737A854471D334FDC58F +AB42867A7B62836A8B56466E9A6C1247D46EBAFFB905CD4321970F59FB8D6FF65FDDD34BF913AD32 +2E68455C5FF2D23C1A5EAE687F259BC982B6A384D35440F7C693CF50B9ECAC0B5578CAEE87588B56 +2EB6B7F42034C9F2E545EC866316552354EB3728C7D26527ED75174EAF635E048B08DC5D23E88981 +070AD5641A652F2344956E9CF4C16E652A99F4A644D1787D6D36537489DA4D74E61B2FC4DFDF1D1D +9D58F9C26C5EB63200526AFD168AC57D5611ADE4D4A382FC28BB60F9E7D626A6C67AFBCCD1183C5E +3CF2EF210D0BF5CFA7BB10FA3887BDD4CD96EEEAA8F9219AA2F10ABC0A960C3B57C0EC0313AE10CC +FF1F522124CFC8D2D49BFBB0C193EAFFC5B48FB3FF30B21CB76F0A4C0F1377C9223145BB0468A5D7 +1B9BC25873EA12E1C60334571C67385C00D0B570D3FFC6C7FF0DE62C183C76AEEB12DFFEE1459E0F +C818C621B8D12FA1357E2B55D48935D70BF140B4CFFE8813DEFD479350B20DC2EB1D3CBB1A2D3DC6 +EE975D58C89D61FC50E6A0197DA9A586B72255023DE47DABEFB11E8AA02414C2FF6258A281219B9D +DDFE41BA7D7977D0D6F18224FE22F7D4E9355FDB35BF7ED3418F4F68D093AC48F7D8FE4194FEB6C8 +0B9DC1F74E023C604DEA27089F98C3973FF9F4AD7BF7BAE601DB89B08D5D8139B95EDCF6C885FFA8 +B3E4B0477E7040225733826BACFD1EC4A0DD72DC41734856AB9FB700DF83CA2CE812913BD142D84C +5C83C0B2583768198AF9E885F2BA74877A414233207234AA5F18840557CA11682AABDE8993533887 +7C6D404BDE4153C9827EB16D66C1D73A8143C8A2D3604FF72CE579FAA3C5224BAC48EA83BA848429 +9472007DE96466B5B29ACC7C03B05DCAA38A48BFF9F214DE43146AE4E04FA705421917F99BC54533 +F0EBC01849E396216B9F0794E6F6C6B61B52EF1B1950C0FB609895C3C55FF574163FC8B6B09E66AB +AED1810E698FF37CC1F926B2CDA3B48C7D77790EBD2D514B6F385D397F713EC3AD3954EA9C846158 +6031D369E8B99E53408A79D64C34EB5A56DE8A67DE91837960E98A66FC04DFA0EBDE21DB003234BB +78665B039D0A469A0221BD541AF7149A2A659C300132C14581EF766FFFBECBA8B58A5EB3F95446DE +F49AF863A8113D17B2E7E6ECDEAFC3834D4DF900E3475596E86FBB4E2974C090DB4AD61A737D611D +92B4535AC291C56AD8B1C031D2F9B505BB77517B737D70AB3723DB52AE2ACCD5DD2F617423ED3CC3 +9CA882EF41757BF7151806A9B8B0F312808863E3673FB54DE939B35CDECA7FBC4DC3BDF5A5F47D35 +E345916C39366C8B4F439CE1C6F1835C320BD1E67375B03B5DE18C93256F251761A4C8CEC01019C0 +68E34447BCC503B9571FE8000627A6B3DAD5854CBC0A2D69E5A8F46BC78F6A7B1422334EC7A98ABE +FE9B83E01DCF3C6C9273B346F3240EA225AE4A4083CC7B0EA141A0773FDE940768358EB4B13D82AA +304A1386D450C1C0C6A7D5A8FD2BD313F78F85248B5196241E31E5595F3BC01F37700A2DD3D4A0EE +2DD01A36569CD507130E8F5B1E96CB560BB7DA15560CCADF3B2C9804A11D9E8055C9EC70E48C1D21 +3EB756A1376F2EDCB7189D78CD3D6CA5865537EEC31C17D801605EFD860B0B629472690588D02575 +02C6F7A75B9A1C1B397781329832CF3EC43C09F1559CD562C48FA9500295CD3B0A790DD3FCD4684A +7C7AC49AC9BFFF36B39A9FB148BC28D37907433943CBBF0CBDAB46D3EA86DC8F81C859C52D15302B +94A9B51C199B7104DEEC9D769C2634CECF8B700CE9C04152CC59C9326BDACBEC4312DEED92DD087A +1C4840868D9F97CAC046581F762F75E8D24D6445370A3F1E0AE74A6478D9DAC37E7FA5BEBEC0A1E0 +81AF89C1BBF7F51E3E2E22C8C405E8671BA85F1BF0DF79A465DAC7EC07F731E00632E017D190A99D +83E27E5C2E63D7DABBA23B2E88334C63721AC5A4CBC5D45F4C177259F34C2EADE01FA008AF65EBC6 +01D8DD16436D86AA94C99F3CC0A2F87134E73BF22F108B825A8963B49C6C685474AFE4A542C8641D +C0375D7EFE9AC1168D9700459BE52D0DA399023E141969F25C0DAC4668534B6647EC85454BE945E8 +26B26DE6E3C4584B97A38E2B40A0D23481BCA78084FE80E00A71A790BF31DF468A435ECC88E60A57 +860BBCA3D65930186E9917CBD209C230E8F8255A7ABC7D3F043AE4D7AD63D9980BEDF062B7D5C298 +C40225B6D03F29A0339E0FCA02138E526F06B9EF47F5E7A8068A846CFDE2BFDEBD24F5A73A66C079 +18662AEC80B43246284FA4E2EE0D9AAB172B1E59A6CC46B801149D8C0DF6DEC9A55D8E1B0EFD9D30 +2FF618075944CCCB6831D336B11617107B0530D09885E5CA11A5F1FCC8D69D603DA16BEA51116D42 +CAB1AA1E4D7B9B4D79993F2BFE53EAC904FEB70B2D330A89780EAC10D12CC0C35B8399F218AC2976 +E57A26BAD20CE2FA2AE2363D3FD2A8A971747556F2959DA74A8963C20B504711AE1CB0D0C02457FF +2E9BF696B159AF031DD5155F21C0F5549B0471A3C5DC8918B675CEBCB23E29322B959ABC05283A70 +2E878DE8EF25EA760F3C5C7B7B49D398283DE2ED837FD59F7C22D62C58FE4448B1049FDEBFC8787E +67D7DAFE9774979BB3802254DA59BCC0219F98C219F84D995CA768B8B5D9D4A32525DFECE003675E +E4BD5D8DFFC11025AF2B468F9207B5B2B42349B98232BAC0759758C1F4A283405815BD7145C93FA0 +8F3ED2826655053A3C2559073D8ACD199DEA2C5BA5F616A2E48548B4370EC73493BA07E197165DCA +774438B0766867819C1154D1959FE6E01E6312E0AB91FC2E2BD240FC8652A2D456A1DE7F34EF372A +53794D4C4E050BF3CA5B7BD2F1B8DE93B4C8002485CB219AD2D029739FD3C81CC6E78EDF38723576 +1A57143EEDE5CC887F282FECD261F6A25D0A7E154ECDF5DC38E426811BE86AAA458577E5E0C5F0F7 +5AAFA9C41E5D1DC9D91ECD79B514F8CDF7A5F1A189470D35FDF4F9B8788879CCBD91B427822ED658 +389E981E0EE5F7FB87692A3E3E931DF8A1D1573E3B0166204240B7080089A09EF7487C9AEE2D665F +5A82F94C877FB5B0DC531CEBF1E71C6592CEA2401E4B5122E5091DF03D203DF979B9A6EFBA12E2F6 +B422FDF15D49AC0914D372D21E871DE65CBECD105FD4A3E4714B9CCA5C6803FA39DBB015EA8A88BE +7913502E562E5B170B87BFC8572DC9DF49AD63694311EF1334444BDF0B4CA3245271C1F7A4D7FAF1 +703E3AA0E1EA8D5C6E821B28707EE0C9B4F22F23796FE87356C58AE2CADC191F4C58E1FB58DA03B4 +5A25AC95DBAE13A293474217BDB214742B9D9D6AF35F70FED2891942EACE3E625E55FFB820543FBB +250A062D3D395BC0F219ECFE0D76686AC148BC41476A887BC494DDBD396BE200FD3E03CFA12EC9AF +6B934A283C42AA05589AA6B4A8D16946BB51F50419CABECEAEC5AEF9085C9989289E9B46BAFB6FB2 +782D84DE2B068F91A9744AAB237CEB1BA513E57E4C307108E993C972A3E0A898D5A8D27833155031 +FDB98863C3BE7FEF3004CBAA5CB60A1F2E3EB4D7290FF5FAFA088B1CECCB6CF51A58DAAD998F0839 +6CDFD68F5ABC9C1CCB8F6514107773C69C26873E889D1F79D10E866910E4684186FCD71C965ADF62 +39BA3418B313A27AD632300969B6F284519366ED85E7CD968D64823F8C59B5911A72D0A20EB72B60 +3A61E36F52F256FFCDF706B4560B4DFA5D918FBC530D83A4B3C01BDD3CB4572E24242D141BF9E775 +36693A0407D002E09CDA5B195BF1CCF430AE9824C07928A050D0B460F2704BE8F9E647A4884C4567 +0A81EACF7CC038643EB0FF18A376FF6F32B6FE4F197273327FBBDEC6443A299CAD4B26F7778A99F6 +5A11BDE047153E764039EDB251936AA43DEE50DDFDF8856519056AAFC4C5AE6F2051AF0579A9ACD4 +1D00775D7DBE70022CC263DCA5E0A25B9C7C4F5C418587666B2FE24816B1E0EC92F9074F1403BB83 +AFC3F1D52CA79C387BDEF864366E34C90BE52F7AA09935373A07E4E026224E76F9EC3CB9E7EDE50D +EFDA48248D61F3CEC880A3B8843306375D9711E58645F3625BDB8E87052DA67F9794EF4AF8DB0BCF +E00677C3A26907DC651BC838C40EC39E2B5A5DC0DBD345944A6C32226089D63C52490FA10B215AE7 +03CFB663EB8A47793B84CE7364DA1C4E7FCE32DFEF09490121222774915BA59C78C2275F829D15CF +4D8686B095C38C731B83D48738C25F40B8ADD487C350A2EBE846C3916AE384CB1050F9F5DFE09FCB +D9129C6270FD86D55A459618FDFA4F907E6B4746196BB717865AB378414029017551161A52E9D24B +E4F7EED553A927933D4ABC8F25DF607779A717909CB4D810DE8F5762581900E224E4B91598149BA4 +71CF8068ABE8744356B261600BFCC57FB8BE45036CF6571D9B2A95304933BD4F17215F8EF53F8E08 +1AF61FA7F9583C34EB5655CB0ECB82246959F09091F36989EBDD646BEDCA614B9A61AB7696B3FF18 +1058A150FA6EC1BE2EBC7F64357A3FF2A2B0491D2F4E0B970DE5B7788B467CA678039B5EF55C88A3 +84578D427FD2CB16C87B0BF0A3D37CE8ED43E0F049AF2436344D5F47C948C632C94A287509282561 +6C64C5D262FE5B24916FFEE982A69A6CCF888BD01D62EA591EEC51F4B7DDFAFFBEEA93FE08D736C2 +0129E345D06B10246A5F57151C198D407730713F32299638EFBDC01367E23EB59AAD42A83AB41B43 +2DB462652E29813740F4680A5D4BD47B18328FAE6BDF4200CFA4CE3773809B45E8887C9B2E423698 +9F6C48D64F5986F563D9A7538A8716082F81936AEBD0461E6F4BD470436D8B7656F0FDF89108E6DD +02ABDEF907731D458D690BC608EA9CED09EB1E6E64C0790C7A2378201CE997FFE0317679EE1D4EE9 +F91157449323E53B4ADA8096CD628B5861BF794543A98F2FA2AB54FF0F25A13DAD43DAF9394329B9 +5AA53CA32749FECB0B2BC035DD1EBD53FF9FB5AD8BCE06CD89E5568091C1CC314CFB1D9821D7F9AC +7C55F55E0A16E39A87D43148201B928F3C42B110FC056189DEF183745F3B637441DE8BD4C3C7EF12 +F4258E306B2877ADAEC63441010750DB4E6269A4C78A0AC01BB3603C386651FE814031CB5D8C1F14 +9EEAFF652A53E57BBD4C8C0CE36A84A319A53BC1E5FD3F1ED1EE72F4C1A9BF264B594062FCAFB22C +C1FDE3F2E3D3C17DD3F7FE0E15EBD812D550227C06D01127385374A11438ABD50048E17255FCD2BB +85122A6FB9B7DA9D5E9DE8A747FAE0DA45A1FCEFE92B9E70A5B2CAC668D4D07527A5C1403267D823 +048BE671F725CFC7474B44FC5AAA348420B2D7C23C6CA066666FD6F2208E329878D90CEF1C2E77ED +22D3BEBB9D547810B189F08920A27E7107F208591A84D463CE2576C70C3DFE6643E4EA93F4E1DAEB +41D46F0E2F56FC10C69AD5034FC9859D31CF27A3A1EE256C93111F81C11ACF1FC0CE20B90BAC9AA3 +27A5C85A7985B951519FD4B03C40BE637162AF41B2FDA68F0D1E9B7602FE2659D3D75955C579AC51 +DF6A552EB9581AC3F712F083F19B52A6C4F560F36C59CEEB0C996AAF1728A2AA45DCAD79BD7B23AB +388D5B0B64A2B95154B6259B730B0F4A72C8C7F7CC93C7D64D9D8810D1F63FF8ABD4DB89824E2D26 +4FDEE916C41E299211DB1A53256E1DB5CDD04862F034D9404B73183A99D3D13D642A663F129B6D16 +7095BEB4EAEFD03DF2FF2F0B6B594C1EE90FDB203DA89FACEE23F1BA3901FECC75FE1811BD701259 +343011262B6A0A9707AAA6316BC3C17F787BB80AC8DA5AAC942D90F80C5A3BB59E47EC767244AA95 +C63E50BF809998957936D3BF6ABC24B0A397258F9EB4DC8F65692CB023D9091FB180C69498CD0C08 +BBEBADC84A7E0016E8F8BEA325D924EB0DF82E75D2CC2CCBF039B11934363D4332C5FBC5EC556BE8 +5EE4E707CC2753CCC43D2ED50558E51A104221C9323CDCB0199B7B83454DE3FDC810D0F362C0299F +5DD981B31D8E3DDA284FEF9DC8F9C8DE138D3065437A7FE8C30572AD06D62E8527AD37AE39AAB0B2 +25F76A25F6C6505241ED73BA494CF923E919F688DDEBF193E188F8C4C154F21631080763B4D091E8 +AD1D2FD6649E0CD9360E8D1A67A5B5FAFC67547CA31C95A5EA8D4EB5D68B9F6D6532DB9B54584735 +9558542A2AE58C09F3BD2918EFBE1699E9C8F2C2A11EA4D224C726D2ACD4A8D8ABAEDC6588CF2AE5 +66528B94F55B823A2A1F7BE19000F3E7579D094E047075DF18C8C868760295533B26EB3ED90635B1 +29C17ACA679C3E88B06998CE5A7A2544B700229F5A6A504BD3E45B276471959C8A3F81917A534287 +39B5EF9E3D463B3BA7318448E2A3E79520D2D245A2A72F31FF7070B6E4624E3A5E216BD103640C8D +F387E49D732529C611F8B971073F17EBD2F6EB18F9B74A67E1997926DF178D4C9EDED435B9682F1A +279C81BB9F60DAFE125845A2FF3B02979E5481C78A45C479BEFB9FEF3CE2BA9BC46C77B50B03E48D +A6D17B76F06F3AD118371ADC69E178C52B5FB4B261C9311874ED07DD6D5B3226A005FDD7A6D53848 +09E7063F036CDEA41619122635E835D2D74CBB6AA9B38CAA4D819C26E95115FE0DBAB4198FC5838F +2C91B7A87B07D734C6D4F4F83444C1E90AA9BFC908A2BAC4B3DEF9157AFCA5248F2DA31CA87BD363 +AC25E9E77F741D4B2C6E02F04987A6F49D30E9038CEFC41BA172DD675AED8B392164411144E5B738 +F3210B0E66B17A13CB9631C33D44484E792A7C082DD0A5382F34C5637653261B1EB6D2035B08B4D9 +1FA9AB770CAF40A103629511F7B43F2743D7E583433DECFB19C21FD4FD0AFCC22A4119E77C87BFE6 +FE50068B22479015BE5A9F06BEAB4D37412E062A45E0CBCD7BB39FEE747E96306F79FC4F2E8942DF +5D9DA0E55AACCDA547DA19D30B8404FA121298B44C9CCE198C708C69A8D6BF17591C5C50D3FC5BE6 +961F7ABA8F366DAE957A1C3730DA4A5B4F035A9274675EE3BBF0CA8CE9D8349F50CABB1C3EA4948A +BE6F9F143592F1EA95404E6909A909168E3279A957AE1924245C356331A75E7008BEE92BEAA304BA +40B7C3F48F74D9018B3247DF50EBD7CE541DA48ECCB1B0BE51A455C3C13C279D4D8676078C3EBE43 +08748D52C9B041D3E7244C745B1F2F742D010A9E60695F3EC4FDC1050AC082B905D6A57E8F407A3B +472F731011A5798965B7B1A307E252FE02C8F79CEEDDEB6E165F1A94D7FFF18DDBDF79477F14E9E9 +3981ABD200FE7771B29D1D2D120EE79D28B9543818527039AC74085EAFF241B56D08220C958B5D9C +87C0C04A14D52AFD475B542D391BC54FF33DEF8D9484AFF6873BEED32DDA4B371112B523B6CE22B4 +0D1B416B64C9370F1CDF2C548F4CCBE9E12E21C36CC3EA52DA232DCFB65F66B22B5E2EC04852510D +5E264EE939BB67AEC4764B87062AEB7F680B40BCEE04AD45C7519EB3B6199C9E0E332661463647F2 +FB7EDF303EFEF84891CEBCF0FAC5F723A9D0476C3F8C092604C87FC69C7A90F4D64AE45A478EE8BA +2DF50FB93F55A3546123F0B0E2C1C40C98EAAE9F0F26B8F80FFE6E6B94B7E27D2884D58B8A119662 +2DF6BE608C5569D7864BB756DF2EDD184B90812B44ED4A32D001C31383A40AEEE9743651F7950846 +15C48E402DBC01C818D477EAC0347795CB2792E9C11E8FD4A02E194EED1C919D4598FEC003B6D9A8 +A0BC7D456047A1C0579453FC1D7CB2D158D466939A23D7A7B8ABED7E2777EC7487973E73F2266D9C +250CE30729E3C5223AD93B9AE8443B35711E446A3DC660123ED45CE1942A1A2AD0610467E081CE2C +8B92A6C82F0B17B5D2429E99F1A6268072C6B5AAAA6EB6283A872C54D3694CD825EB2926E57DBBC7 +C1663075E687A144E4D61C225781D80FCAE1497B442342B4A3F1CD6BDB50E31791CC3928C30835FE +F845B6BE5E2D7E3F2F5F085AA3FAEB45CAD0D76BCBB1ED859A9CEBB9F7457036F0BC3F195CB1A98C +9C8648F6583CDBB23894BC719D68C2DBD8003B10D08C8CAA40BCE784D7BFB4EEC9EA5359AC056E57 +B8B0F2EBCB1F4CE40C87FC7861180133E0CB6CE2FC4FE690756D327A2B5AE063E3021C0C0BD420D0 +56F0B941E6B36088A55BA11D0C35FD0132D5F48E5D9673572347171B4328D4807B972831C0D74CFF +A5638C145B89C989E6EC942148207D6DB82257585958034D9F9D4221C7C9F7013790DBD130F277E0 +BC88BB179DD09E27062379ED06F25EEA8B7FB33C35861A0034776E3813D2E9E5C10E227CC569AB36 +CB2D9DF2E7B7B44758F9DC4FFAD7A24AC7E9F47AA850C221048C3CB35A37CE8EA75632AE65FE3212 +175146FECD6334AE3D3C5F492F067F795E1E8FF386BA198CB74F0BB4DC0000DA383BC4CC3F070DE1 +7721431988D69C8B1A5AFDCCC83C22E16A87E01C6D3E79DC7AFA3DB0371B0866EFB8B6F88900472A +FEF1C4A878243C52D4E02E82658979731C841C489A6B97E271C4C93800EC7D91F93EB9B9C659A554 +E1FCE42A5EC65AC39190EF4B66DEAF6FC0569A000A9E1495F42F706FBEA4D32EB7EF11A648910259 +6A65CF899C2F322F5679C6D123469192A9BF1A7F1F2C81C554ADB97BD19ADB746A4F81A4D5559E60 +AB94C483DBABF6CE2F28CDB412D50FF3FCFA3B3DAAACC6A83CFED910CCB3B8D2C19590AFF4D75303 +4A6CE7F4156896A13808E0DFEAC547E69D3C886691728E4A35ACD575B40D721E8FCC5385A2EB28D7 +08101DC50811529528F5CB0C009BA7E3C88468E37768FB0D83895AB54DB2DD5426562AF9D8AF304B +F6EDA54E9C92643DF926F5C3578269750120302A37CB140A18BA56BA01108D4ACACE8FEAE640A6C6 +958EF156B588ADB0EA5F3B0F37BBA12B7BCB221C811415387B024B7076FA4403A3AD6EBB5D9C26EF +EBDB7ADE7C60B444AB9F90EA493B658B7767AE2BE649BDBB3FE85F460F1ED137C61BD95F7CD3D8B0 +15CE45138538930AB62AA0E54B4CE1A5EC5FEC0A2B28B345B67089A4E4AE14D2E1F5A9C8848DA688 +CA298F93860649EC3AAFEF3E820D86988C8E3E5A4D4BB937791827994AA3E81D0BB3EE115EC36D5F +B9A392D09E79AF514D11C7B3A03C9F9C13355CE79E119A19177FFDCA34704D38118A8976D1EE5AA0 +2D14FEB1414419F5E85244ADC5C0A765A522EEF36170064BB19FEE3B5F7B441E4DB967DAE0BAC2C4 +8FC6A836E0EF5A69F073BEE1699F55E9C757EBD6FD8B514E2B49D6333815B7DBD1E0694695FCA3D2 +1320A0C4B852D9706DADD8369A95FDD917328BE93DD33818954DBD2C212D2CA81560ED5BC284EB04 +7A5F389E24E43F4FA8C97FECF46589FA7341076555CF55B1C21B28E0C1CBB00AB8B6F67472F27BC0 +D11148F407824B0159B5188D4BB7386FBDBF1C0FAF34721B7BCB5C0FCB7C4010DCB6A1284E9D7883 +9E3C2111A05D29AB7997073B590A81C6168020F1D48951BC7D8476D5BA593F4F23CAC1F9BB0E091E +84B4E99E5C584D1370DD12DEE8DF16AF8BC6B7B23E2FEABDB7F32779AF8E2B5094A6E9B7A7225F24 +C43A8E5D2B977E1E19E633C26771E23017ED233DBB02C64F8CF03992C6484528D0C8464B46F24F9E +8380F385D5D01B8893C67FC103498983CF939432AA380CA576D09030CD52FD99BDC3BE16C7204CDC +3365BF76294A83A1FC14A236F5FE5321904E779B13232A76F8FE521F425562678436359C2461BEA5 +AB27209541F557AE2AA60009C9CA0A9FC7898C14306CE35A50017BADEFDECBBF94EE2905220706DC +806409EF87DB1D73EAB0698AD2DB72CDCDB293E7FB13C94D9FC87E74502E6927A212F0D7D2F2D194 +64F7A66AC07872E18CB1DDE8F11835DCBC5C4EF039333FFFC0FC1456DAADE7DAE3EC2EE0D3415B0C +ABB69FC5006F4D14A4EE1A5CA99AD4D5E629C0DD1E0F097B5B93DE2DD001A8C418234C9C45E8C13D +1AE04E9466DAB8CF1ECB88A4E059C111A6468D2DABB90DA79C7C79E94DB28F6968B1A632F8C57D9E +565FF91C6916026FFAC0661856B9FB8DE9C81661816221B1FC159CFEF1751E7E403F5F2CE32529DD +540792FC17A12A3DCD7C50D38EEAADBD10ADBF5D8A82442AA900CE6150EB7A4639DD9FB6E385B2FD +093493DCCD9014B23EB172E21AA89643A6CAD1093343D85D81261972DE0ACB16A4C6B5F0BE4C978B +FA12D3CAF0134F9EA49F6E9687C8F99A456745EA252F0BA9968C7F9586E3DD841AA92DC7705BDD68 +2DAE41518A09DF0E209F321D7FA3417202F4BA76A984DA3ADDBC58136885362F02F0A24EBC439B3D +BBDACFFD8498EBD29F88F016B1FEABC10785438EAC860B554525F3266097A675299AA0967BD3B7A0 +EEEE3FC578D1BE99D3533BD91571AED904BFC9DA1A1451FDC5406E1CD614E0C7FBC733563CD6CE6C +C31E9237CA153F1F0411114361D731636BCF98555ABF12848AD109371A42B63675A4130B81E97C2A +2EE2BB5D8FAE2640156001AF0F55D9D5DF8FF23C8AEFE14F120000F14149A36E5C94CD9081DEC277 +C2C34870D05011F99D48B0875A5FF542F067F7E9880109F586BCF2B50522A1F23ECE44349E539E70 +F84E207DC9BEC7CDF856A046F1A03226AA41F541719AD1AF88FF211E57DD0C1275DD0B7B47440DA0 +89B98C6EE92A7D94700B83CEBE19EAEDD8A615F6587587BA8BBA3CE3AA5E8EAFB1FB0F486BE3609B +169EFB178A4292F4C0378AFE5D24EED1CAAB514DDC66C696D8E37F294A6579131DDF5488E9436609 +ACD750C3DB0A940C84FE022B22ADC2676F62E91E8F891225F891FBA537679B24547BBBF35F04915D +20B11739F620D18B5B216921D222F15044368569AA302980B9225BB839F494588481B94B0C724352 +B2DF600A22B062561D86CB8F81514FBDAA4F8A043A0265F992FAB71FC9124A45B8475E1EF3DF6B6D +E35CF329777D45F08325E8505EC0D979F542807AE77E57E453525F23BC59A50740371EFA98678AEE +6C425374AEB745B99DDB5D8D908FDB551FBC0DB15832107BBECC4E11A1A8DEC69358A574A2ED46CC +31D564549EFF23102D92BFDCBB2BB985F78F36033E34F59C0EBAFA3BDD71338736464CEFDBA91398 +33995EDA4207BFD4A9867D32E867FBEB7DE60D132803EF9347CB17BD91315484EF6570892297DD8B +7D966103339535E28A00CB1EECA4A9775F60A9F5FC9BD8B06D78FE8E6318C31DA2E847E3F9CA587C +B01AE2BA0A2EBDE308314413F4F230A758184ED60D4F71F6CEC22A93A01B6C54E0449A3860FCA895 +4A347B7588329A80974ECBECDA1070FBC055666375229F13DD995E99265DF870BC8B8CC6347FADBC +1A6AF64599271A475B9123493D46BEC41289BEEB67EB97A8DED7A9C9730D37C65164CFBDC22E5CA5 +89D2E7954C7136EF4E084C43A6C7F361A3E96989239BDDB9A593CC2A80BA16DE9EE90E95CD39393C +212AB22EECB677FD36D34DEB46C4AD0D21BF7E6D7CBD0C8083842FCD87B18FEA7CECF939987E99BA +34C214E44DD84C176C9CC5A4CEA76D380CB316BB4EF9DE73D73B4AFD4ADB54451591DEF86621D138 +D5A0A29441502BF6C2ADE671CEC3CB5CAB903A657EB2D70C943F976C110E46C5D9D29BC00A875F27 +38E5D22496A43E096E009C5D3CB724B4CABB32838DBE527F83B18CB457E57B092C302EE557FD4F00 +DB9C56E66C9FDF4EC9FFAAB85F60D02BA79694FABA476A199A0331C30A78A92E10417BA236E23364 +8174C826331DC1BAB87C5F95027846130C6A2B4027930EBF9A97BA1B039D386FC51C302648E25980 +212F6A582CDE2778C677A01FBFB3C5D1B8A374ADAF6ADBF7DC94075F25ED66D440B3922C5F255FB2 +3FD8F6E21EA65B1D93BB225684B50F11310E242B087575973345B229BA62C1E2C35BDAEC04D10148 +F5B2F3BCF7399BDFDF1F3F79119714AEA697245BC647316EA157484ECB951BE367234FD02E8B1F09 +1AAC3D29BF282DFF4011BC0CBA8E55234D943DB3017CC7A766720BBC29B2D097A956C0F1067177F0 +12D42ADCB473CDE8D1BA35B4030757FA1D8211989DF3BD22CE5D501C21EF8708FB3449DF47D88650 +9FF7B59B76C0DBAE443F336FEE2D615D7EED1C284F14335BC8A26BF4621E10DE9611FB2F1DBD52E4 +B7565D8C65B54EA36D508BCF0C578A49A2665227CDE1F9768EFE847F9D94F1BBB7DB83701C232198 +5C7283D47B2E40B27A268428AAEFE75F6B2F8764A8494E5827573758CB9CA46FA93208836BCCC8B5 +564A69F5AD882052AF1C1417C3FA7F580569528682C77080F3688B65E7FC24D2A3AEB61574B4A321 +5927281544DDD7A6EE0A3E9388F8F631CE7251724DF70726E5912DDCCC8C652DD6C9608F8462303D +867F589DE0F2F71711B35142EE6EF93B64D6326C4DD7DC83278E057100EE772082E6BA368ED91A55 +53ECFE2293A481E42F83BC8F9148C70EACE91F7B7D9CB8A72415BDB3AF66F68EA733A17ABE9DB005 +3BF148629132969589F38D30EABFA96A01FAC72650B5A6FF3935670198A1EA33810A9B11E330EB8B +451F24F93544263436F669AB5A90A53B16CCEEAC36B1445574EFA7E802DE73522BE725E68704822C +B7D3912717333367895BBFBE06966A5CC653AAB5E9B3596702086BF0010085B900711932A95ACF15 +CA4DC45A754EA334E9EB84D6FC8E3FC4F897456BED64BB93B593549FF0D5352275D8E417172A6664 +C5E0ECED1019494A7ED49AB0B965BEC1A82E5873766BB38D7D856049CCE2FCA65AAF61E961B60634 +E2A69EF059754C9D8163D87F928C222772D070D83FEC6FA5AC734AF65E40BFDE521F7D9CB1650FDF +64754BFF21EA3FF0AF7611A93D525EC9B28C51AFECB04E7FC8323DD6C9B0D8539A34FC3CD8CEB795 +8E8EBBFED4313C77ED469C199552A9FF70BA5423B03B6148D4EAAE17B71C5B39DC436AC53D6BA8A7 +AD81AA8B02335A8B2B11E9F4FA913159A725B8AB60F52F1A2EA50EAF4D56656E615BF382CC68A690 +BF83DFF24FE986570ADC0290ED1A37C1C2AD469CE789E0EA0BB5CE01020100E729721AF3B5BADD33 +A2DAA6C33EB8F9064F5292F715F820B4BBFDD56F76D42E7A1A068C1CBDCE4640082F6E7D582D1939 +990CE6EE8D270015A2C461798B37DCB5798EE9F7512168B76D26C28BE4A49A1BF96C89D235F21A1D +B6A96E5DA474D0B19B808D13D7A11BF39EA8647499C410ED9894A1ADF33D41B6FC2E614D8087F4C8 +4E437B136F3CB32DB8393C49177A0675A0C9E7EECEF448A97AFDBE840FA01FC7E5F2E8FECEDC1884 +84C312E8635CD79195475DDBFDD4D38D5A0246DE2C7F21608F8D2C0DA1371D302E941572E5792A3C +F4E51A33228B93A814D03FD4FC223C314CF3714BB3A34BD4F7ED6348577FEED9DEB082C4049E57B5 +D3CDB7F26629E9F3BA36893E09E3C7463D02A22D7056BE76B87763260E46E48BB832B7EE13F8DC05 +37EC8E81E9BDFEAD8C27EBDF1AD706933EFD11131E12814F236EBB01BE85B7F1B2D627413B324918 +D247604F56EC128909873FEC3857028BEF76A3494364C2A7002D104D486236C30B48E2B75D851C34 +EA50BA7FFEB4E19190898AE21768C157C0CAC628A2181A32796FBC1A7271D2473CD88E5395DDBDB1 +FC3AA8DF0F3D588637F19A8B833AFDEB5F655A8838EECD684E2315B72C75CEEFBCEF94344ACE8D6A +DBE355008EC72FE7CEEAB01363A895F4E73F867639BE0A0BE67333848816B05B419221BE8F9066C3 +62C23FE85B7F392930BFE4C12B9526FF2FDEC38F23A159ED61A0718E7115C24597D849FA76369153 +54A40C965D4D72EC94DA61A03766AB39AAB684E134FD1407A5B1B19BFEBA52AA0DA5D99CBE5C82DB +AA663711E6DEBA180E1D4A39C320516A4350D296BC19BF1BE054859A0889C7E9727A021F3176FE62 +0FB0C837E4141FECE531A950C03D319E3255703220B7185BD20FE5DBA673F8129AB211EFCF36EE39 +4C7E00EB0876624BC840FA86E58B2F584754CB6BFDFD76810E300741EBE4544E5AC17413ADEB21C6 +2F66CA4F075C32381796BA709782DE34A675B717A2C7F6D88104CB924FDE5DF775B4F0B68E0E2E5C +2F788BBDEAF06D8E1FC2105CCBBD5827C0B03FD6CD64F0D073F3192D5F94839644E5EC6C5185BADC +F04112A65F49A8C83174A9AE958E76A2F5AF469E8B76C833782C5FFB8BD7B1BBBB3EA0CB7C9786C3 +BE2ADE5E7AFA8C8F20892659A59BC421E28845A108E34EE17864042EF587A6D67DECDFB3F510EB40 +D2229585347A0035670FCC76C2837A4E4D68304FE113C539B35C1F0234B5079B8E32934546982978 +C5E4DF955A454EA263C3CA5D7101F31A318D82A3F9FCB5A8AFD7A65209663B0FC9DA400B26F285EF +46D0E1EAF8ACB1F1CB805E3986D04BC585073FC64895E4DAE1CCB749BB439CB32EA91176D5C39C36 +50D10AFB9C9884D5FB90183424CEE67EF2175D01D2478D67511EC9F54F88763C152697B06D948BED +49240096EEE3D06AB4575E8E8B2CB8263B5BCF4FA1608720F52B675309833071879DF52C3EC2871D +20F398B5CAC8F8A4D41D0F1D47584DD90DCDAEA4A1CF160C4B3BF1AAB890B5CEB6CB3488672AA68F +BD938281DBC1D8BCFE92FBF514DA5358443CB6E0147254E91B38CE6787B2BB0DEDD2D38F5938737A +977B5EA42892520C58F8FBB53C994B57382379E9490F0D6970B980E1BDF8CF9F4C3C5E0A18F66E86 +EE93FFE7FE546DE50F41364BCB3721B637072571FA1779F1D672FAD260C16D7F13CBDF3E4376E7FF +56D2A710AC5AC35FCBDBCE2C9C17E523BBE6218617B13C1FA6679B308979AE7C61DA6E68369324C6 +CBC7DDEC364E5A86707266C0B459EE7B2C03FE584E529BFFDCE98C90A2F3D9305AA74D3ED8430DBF +3A49FE2ECFD9C4BC9FEFD22618FE9C8A973AD072AB6F713E4DF02DCDA7AC5359B2D652013E131B76 +B3ED6C75FD53BA58D862846264627F6B9E70D8800F6D9B32242B747A67BB2B45675840D34F852AA8 +062FA6B01E31ED24DAE02F6CF788A17F7B9368175195DB0072259CCE0FFB2C1035C1D26E1777CCA3 +D56A827C3242069E76D6DD69B653768614B9ACFF16567FEA61508D51454BC02F6C60F755AEF6AFAE +3536BBFA1823F8E1A53C41124DE983E51CEC92AEF4F99785D554488A51C20885346D1F761DA79017 +940A0C557D93F1DB6B3D00FFD61D08E96FF3AFCE5FEDF545CC9F47A2B1BB26713431D6D1E47FD6BD +6E3C668B0368241F0EBB5FA9C991DF79890E52E83A3675EE699B61BAF869DE91F67278F510061C6F +E41DE2D883F48CD0E068E2A652B244128D82E5CD52F35F210DDAE3054691ED55A7D99088AAE8FB04 +F525C2084AC09F5EDF80A4EFAFE981F74C0DE9D194320709B3464F3FF2C0F6AAEA6D973D9C323F53 +DE3D741F698FBF01036716BBD62957CB32CD81D3A2674560FFBC5BDC5C6E4F547E589AD0B1CFE14F +5E17FED1C4A8ABE4E67CCF8A49F32C4C6044F1431E1CC382E7758722A6D0DF9ED23E51F8AD14D11D +7B6428E27443715EBA4E9C05D6F238378F9498AEF0E7EE4FE6856622CC8E6ED141EE5F109E343CB6 +695C4BE1E0F66601C27975983BF557C04ACFC19227A1AD7E6C44C00529FC7EDD7F886D24B7E029B9 +C395260088BBFB96972199A7B32796D27257DE83A7402291C14FECDF7998C5C96B1EDADE0280F856 +8A8F5007852EED303969180B3329917973C2D32C080C9765B6BAB0673BC7ECFDBBFBEA980C263843 +39B7F1052591D91667D4FEE413AFC23DE2D4B9DA742F4269C6C939F5FC32A38040730A018155AD73 +3F231E4D5B9D01C03A58EAE7B5F590CCFAF25EDC8552CFC8D95C60EBAE1837D7A97CA137E9D4A4BD +2CD34AEFD68D64B3F4F62326AC429921D7FB3C235184FE0899690A0B775F1A566EC29D5830D32372 +6526F7E7F5AFDD71B77E07613DDC4FC63EDF49051AEB59E6337AC0A4B6DD872E776C9CD0CCB86130 +5322D816732124F5978A86C186BF0A0F88E733CE38E4D7C1BA5378C5629B1EFC97806059990ED42C +5CD183BAD7E94070E4058569DA2E51831FFE0D080301AEAB4350BA290318AEC582C78D05DD92E5AF +B4424EA808629BC972E68F4FF2489C245593F07555CA6A2B25964794CF31CBD3AE5C229AB9B8C298 +06C01D116EBD0FF0F159ED2D3D7DFC73EAB4910BFF5B0B0B587CD9EA6E6FC45D63C09766224D8346 +1F0588140B258B1729F70BAE7962189B1554483392988CF230AF4077193E53330519394DD99BA135 +6D4730AB221DC6A66019BFAE564893DDAD7B177DADD16ADD21D396CFA6C3DC818052E2F71149FD59 +4A16DE0C2FFDD366C99B486C55A6E991E4D22CCB15843F0C3363676AF2F5B2D1B7EF66CCF2F12DC5 +0D63776BFFB058D70A9C76DCE96C754872D72C82A0C33F90D49C935402CDD26B6D743B1F43BED5D8 +B539424849C1495DAE73044E885A7D0F307F1816DF6244A6F2D97BFD4E200E93F69B08AF39EA21E6 +E347A47CEEBF803F73B978ADBFCF056789BB8E6E2563DE87DD9A8C877157B934102DCEDAC54D487A +1BB2694F0034093C48F10A17D32E2BDD0C723CAF59ADDD1BE373AF8C9BEB4415AA5AF36310C31F24 +354A53C0B962573148BEF91D994FE3F3D8450DD4D686725799F53C373A0A3E3C060C2E1A3E800504 +9F26D716E1F381B9F83125E4683264A07E2D8938F605978E2513DD2050B3D8A1012797CBA8961632 +BED260916338A812AE751C7B657E086A0C7DDCD3BFDDFF3E48B84751925736D1310C4910FC114387 +F3ED7FE163F91895EBF55FCB425CEF5729D99BD8F2C072E36C310523E75CD8E5DE49C031C4263410 +9D56E91A46C8C8E89FD92012A00C33D0DEC52597B5C6933291A7BDC5CEDA95DCDA5600F9AE1C8250 +54E7EE1067458CCB66610704C58E4A4FC0CB5FC933D0322A716B2CD430A3AD48DAB3D4CBE9D23F2D +092368CFC4E1F5495C133A92942EC62118D45C17723646E69407B4A89DCDFD2AB3FFC099A21D9D29 +741D68270629AA3A414FE58658DC9170C247B6E23F35C4BC5FF83009F462F2EEF4DBAC5FD158A658 +57F9B6DC1F5192DFB169DCB65621CAB2F1B07BD22F4155A8E9E2B6388D430FDE5EC1C834D22EA035 +C52E1E34482EADC36B4CAE902AAE89A7284E62B3C84B608D6BD05F75BC31310B2DD3B2C08A00E073 +7F104F03A41989D5F6B9A2C38B22F1D1803EE5D7A4D8DE44E4ABD496A1DE0C0E12C4BC96D0122846 +3F0EA9CE9509FEE987139F3DD3F9D0DF4313F555BE85433718F6D05F197C41A9D9C7A8B0D2740196 +82D49F58DD5F66B12A6520D9F226D1DF1F1B65CDFA261F980CA25A92645B86B64606293F8BFDE364 +C47D2AF2C709BBE77A70A5712F2CC26F3D66F5BE2C307A48E6F887F681D30121E32BBD87271B5DC4 +615D28C309F15AD263FB37424E56DDA6E17B998B45BE6C7FC6C28E3394A8764C9EB2DF5C06626593 +B5C665D550D4600172791CD208AE9F37BC082B0B242B0A504B751B18F4D7495172B697EE217834A8 +A4FB7CC16D6F9E8BB400BE8AEB0850960283DCE725249FCC4DE97D9886745AB6066C3E2F64DD8AB7 +9AA11667F11188D7965DC11EB760B772E282DBF13249F31986AC6898FEBFE23E3E8B8D2C33E00EA6 +FC493850ECB2E6D831D1EFCA3C2EC8EE2E394599091ED58BEDE97D7A43B6F739EB0F845EAC1DF6B1 +EBFE876009CC5D804B15ED4B56761B3CE1AF59C07B49DC798A44532297AD73D5101ED47F36A3678F +818297CC27F6AAA2AACCC9AA9B6F5459911D8C56CF499E390AE607F3790450B2B9C9BE0F006EDA0C +715B5CA0481734CFB0597478E7602B0D2C1E4F78F03C68C17C70E4B42D7D2D3C95CF40F73488B371 +8E2CB05A549944D86944D78724E266C3319AF89AE430E777E95F0D792B1C654306E421F3D63A26B2 +1E74B6E8B21B2E2B9DC596D013CDA16D08E65E8F24A84B12B2BADC653E6E1110DE2E709C1C1BED13 +707B70A421B384F20CA7A9A9D20324DD383F28B2D3C7A9C53F5D4C6B7C378D26DF11CF55238BE1B2 +4FA70DCC178DAD3D35670FE4919085EB1CD905971D76A368FDFCF9D2F0A23739851A3A6D2E02D65D +54DEE69ED5D81315D3EA5E356F94EF256DD267FD1E1A9EDC9CD63E743F299BCC4A4506233B8DD765 +2CA067F741603F93250C087D368F9E9CC4CC1A6DED567487C05BAA992B0056A77F630A72008E3946 +15A9DB24FE56A956650EC9DE90A6C2259189440247970541CA198748928215C0E132A81AA13208D8 +63C1FE817F70CA573B54577D10B73100AF8EA088208A44FB92ACA314AE5879706180788C17BB1D0B +81B6B95A1C4E0F9EA66F9B39BFE12444A6446691A7BDB03E0F03D9F07A10A7598F2166F108529F34 +CD90E601FFED3479ABCFCBDE8F051C348E48C61D95B00C59EA1287423F05666C3D36288844067E83 +E14F6B5210842C742B89F13ACD126B9FC50ABE2CA7D7ED513D43B6AC7F41EEDA416BFFFCC5C844AB +2D23D4DC09B2D510504CE98D02E72020D9E669DDAA344C63A1B75632F912A1C0DA3885DA4AF7E243 +E4A4C6493D6595BB6D56B0359106957259E59E336BAAF35BD1CEC5CDE735272EBCCAE8D4904AEBD2 +B32610C6FEA2B69941D6542ECB44D71092A3CF067708A3D087AE99FF29671AB7DD8758759B971A08 +AE1BAD78270D2FBEE37AA2DCB119D72F6C7B0C8509018A70D0B0BE2C6830EF8E0B24B1CE1141EF87 +3A4D7DCC501F808BFD94E4DC0F2915AA023076BCC8006490A43685EA25AAFC187302EBDE7FE1965A +04A5A398985D29F08E085127B56B057334D88EB638A4DDE64AFD204974C3939536B1B66A54B4DB81 +151853915718F70813F096CC1B0EA25E363B49264C2AD17158A4489F91453FBEDBDE15D7B74D7F98 +E81DF23251785D58295BA297F295AA6248A912CDD4F1111E6B628EECBB5139709E76EA4AB743CEC8 +26621D08E6BC64691CC90B3C3C1778931A28D3D5B1E20E96C643316613FC487C9B604C43463FA453 +3BCA1236286E6F5A6EEB2F1D9C34BDDE4595495A365F88055D9268541CF1654ACF478D384A5496A8 +772EA1402751A093582A6625A0A44816B5FDBE166835D598644296249B92CC90AA3FD6445C9A19BF +27F59CB0616C7306070F33C7DF4E1DE64AC8C5BB2FFAC1EF2B1B30E5A0275E6004CF64BBE2C6710E +DCFC3AA4ADD60106334708862FFA6652825BC84842736E47AE6917180365C75B27505EED3C6108E9 +898A780E20C3F606A860229AC46D0471ACA0187D6D539A1B8820F620F72B41AD1D3BF3834BF48CA2 +AFEA8BF535AF74C4562DEADCB63D2F5C7585722B77C989342D190FF926C8A5263B4F25286F99CF6F +C62EE6E2AD61C82B29D82468AC10FD27764278E5558CE8B41BA111CB2F040914451A480C93084237 +CAC8F66BB7C6689F340B8ABF0150E06D5B1177278A4C08742FE22F42C28680F190900344ADFA486D +59718C25D37275BCE4DF981AAC35D2C7E85C72A0188B8953CFA516FD545AEE0BF4B8BA301CFDE214 +4241FBDF3D204E3D2823301572E23F204C97305A82401660E12926EE7BA6EA1A81FF5C007933AFC7 +3266FAC4C134ED818A48E7DA01C71A46335C845F9DA5E960B25339D551582B375814148D94CFB781 +FC56093827B78578A73D4FF67B6B87F40CFA5E3F4325D9108CDB64BD06427B88C84105187316FA29 +90B4E3E8EDB6C78ABF164F4A9717D523794B2FE772A04DABBE688CCA977090979B5F47CEB90A1DBC +167D305EAB231C9F4260C4AD10889CB785169902FC0BED78DA15B8417453BB65856EA0BEA5245BA0 +573F623D215F6C0CF801851C305B355D26B52B0B343645FE25C78A3526841EDA480919A1BBE5F56F +C10ABEAA3E1FCCA7C43EE560F067F1AA2AFD642F769D1ACE8E2AAAF38850F0D757CD808C921D716E +96FBC07DA7860DFA70CEAE2888C0ED3CBF9586443532B68DAED9A926655C157A416C383A53D8F283 +2A4E67468112A09ADC837ED8EC95F70852921F50D4417239FC42EE3624CA97F682745CC5E76CC7C6 +7BD99F2180F8C0B7FB49539C8CC474C25C0DDE491671FF329E51BCFA779346D4686835A3AD6633FC +B5E0F67E0CA9CED8F215BEF4D240453EB2EDD6ADB22278AA5B985FA140C9834D38753DF2014F8C0E +E6DAD19E8FC54C03C1F6CB0F858986691D99592562CAD95FA0A5B2ABE4A8B54B457D42E8C33A2D19 +51C0419A72FB94FDA78ECD92BD2A1416459E9DECA9469F35E4C47DB531726DEE8F203D7042EDB32F +025DF3D582547BB1D45F7A5B70D317DF4EBB16E36B0D798E0932FD2A85B04FD67143E4B287A50416 +2C1F5A037CCD780088C5476385AF8168E12D97D44B0630621759173C8F1E3006B5B1C6D7138B7EEF +C3CC5F54E24B2C3CA7B41AACFD25E554880AAF406EA4C3C6E21D3B550B040FB1952598A7E8E6488F +E38288B2AEB6C4718338598A2BFE4D2B9D14C65732DA304C16FF3E1F8F03046EF095B65FD609DA87 +EC24A69278BFE65C905CD0329F6A486B8525B7EEA4F7AE56C2633CD83543269E8ACD6D71F500D82F +DFBDE7F7F7B1AEE67328549232E26CA55085B6E84D9E2E7F74068F93A90C4654F2F396E57C5F76F7 +E61CBBE523DBFBA6E76638BBA3064DA025A79E3A294FE7F1CC28A3B4C57DD6FDC48E541A85534B25 +E1BC11B4F78019457239EAEFD4BE9007D205F1D985F389DB22400B279C10948551A6B4A17FBDA0FF +C9428B18B43DC76EFB15FC2182216F1B60B4E344A03AD6C00F141EF99F89F24C819C3E32877A927D +84C2D006940F39CA8B71E5951673EA9BFD1749923219DE38929ECAA9CE43B06CFA7DA1BBEDFDA56C +61FF6C24F40E59B13870D5FDEB82D981154FAE5D6D5152DE69339359461A41A9713B6BBE47E868C9 +33CD74C75DB71D13BAE4DEC85E02FAA14EAD6C0A253B16C79514657B15E68CCFF9EE6AA385CFF9E2 +C53D9AE40F85C793E4E8FF50B2B7420F4FE69807BC5F37C3E300E6B3C3549D1D3246A2E70F091054 +1135BDF805E0A698E236B6496702D061241687B7B8D1A0E517DF0476DA09D89667A7AB375FD2672D +CBAB8124E511502DDBD08BA04D941DF1CEBDCCF7ED48405CBCC33774A68C5212FC6F132641FF413C +984F8B43BDFD7B1A2A3435F15AF07EF4970D3E4A0BB947C181E9CA27CC14A35BD1BD096875B45873 +8CA244F88C28728B74E25CB8C4FC1095A56CA75E4569AD3082EF194ADD11350DB3B74B96761D4538 +596FF7243B1E1B724716A144106E080D42036444FD472998460CE9ABBD05B42AF9389AC452BDBBA3 +A13A96890025789F16B9D92251FD3B3BEB2C61EDDB370A20456E3BFE5F4039E2557C451C524F8087 +015BAF3FF05F51869FB97512968BDB2B49589C1C7AF1E085250A47657465F480B7023E24C76731AC +0EAB6704123D77977D3A2C4C56B691346EBE589C619C04515D34F81FC6A17527D5D8319013C5D4FF +27CC3925E24C99231AC7FB9EAF0BBA482D3B75807AC85D03CD09DE5D9AE0B07B7A813F0449786500 +0AE8A7E00080300F0AB8C399057EDDBA273DD2E1B2A0DCEFAD3B332E6D4AC1FFAD846167DFD70E03 +46DAF84AF292D4F424256ED5AC4E104F80697050D50844A708EAC9E7F7784FD01646F3BD0C595CA5 +1EE6BD607D254E78ADDC5E15C3B6AC4940EC865A5C23105B6BE09EA09F2C05D6D76960A843B81EE4 +33977FAAC3CBDA85CDD2F4DB7C28293A77825635992AF8F3B38B4480D9A139B1662345A8ABE1634A +77496C3F57597D2985E9E54717AB2E99CA35789441BCDDEDE9A9E2106B401D9684ADBEFE40D607F0 +75C179E9CC03E59E65430DB70B441D43DF03F2AA6FF06F224B6E455B01C64FB89EEC9103E48453A9 +749B4D602808C7E408A8903091D85E06AAF635D0D529C3CDD1B8479AC0F4208C284BB678A547F2BD +77BB17C86D4560434F7AD1937760A6AA55B614CFA9FF8C9C96561AE6C8F2121C4E20237428BC51DF +2099B6C49E3EFA18E6D439E6E6981E746EBB1DC461259D8EA0F8099C47CCA27B2D982B72C9A07CF2 +1B3C05D6E26E6E286E348B8944078E24809F9C5F3D014B4CBA02533F5621BFBA1F0EDB776C634746 +703C9F73BA89B1960A496420C68F54E5B901A6D733D7ACC79F275FFFB253F389AA480084468BB34D +A1E797E43B7F6E8CAF5E8C93069A3A2730E57EC39B677BB73E3F07C2055599F7062E53B37A5F0099 +907D2ED87FF7A82C95FBAEB888033BDFD67BA3A6031A4CDC56CB1E4CF5B06B46E16D988BECCEFACB +9E1C037023D7BF5CCF5D65AA66A17AB361BE7981F132A578F3ABFB97960A6034F052D9D5AFDC0679 +782EC90F240F943A5F9A3D969ED7399254FF67D89DF668F7C56FCEA1FFDCF20481474AC8495D3AF4 +B6D7EE093E369C057F0B70858220693B398ACF8E8143558132E4391405E30A73937C53402E459F4A +A3539CF7A99A3F51C0307D045DF8B77757E92EA2F51BF0BB4F77D3904DD355665870C2B59F1ED7F8 +4FC71FDD7F0B6C5D3182DB77827CA6A2060D2B8C83C4EA4A432EF43A4D0A952CC6CBBE52A9F0CD66 +1A538973DE41FFE9C5CF55F2506B9EFEE51FBAE5E63BDCF5528499A47C031163C88D3022606784DE +2F46A9C9235AEE3D4F71D4959B0CFDC5B7E78C8C0A8F9DC99440C2263DBACB343C5C648577F5610B +50EAB1CF7FD02419EF3941C7CA0B0E64EBAD4B2CB05A0793DBC38F1946D44767BD287F5E9779C611 +CA0DAAA1E7393DBE0683C8D3455CDFEBC0E64B54B737E298DDA605227C0C4BBA87AA3EC7FA6EBAEC +39E6EF2537D5974391D31739D9FC42983D81AEE44711C823F35F8E2321AC74943871739D2DBE9748 +FE68592263E7713F27E0D49B9B5CB7A4E55DE54E6B800D15856450FFD3AE5F287B12AE4F438B20AE +9E27E6CAA00F3EAEADBE08432684FDF9931E925544A680182602A3C1997DE5D0630BD5A010535E66 +E1C123013D23966B3545C7431C39B97295BFA4099D14461004C42C85095EEACB9B47C593BC6DB863 +533A8619BAE09095DE8ECA432D4DDD49AA600D277E75DC3F5C6631E2A05382CB007825FADB77438D +CFA78E252D79B6A196D5164C2FEB85D75ECA25FF80B1D97FE10E87960CA0FC47C41D3A213BF141B4 +8BC3AAA93FA86245064668394665BFD52D12C3BE4CE39EFD8111754398A944C3FD1AFA98EC337BAA +AF899D35E804CF416AD7FE45FFF13FC6354007501043F98FE8428DE8013901BA6A28711A2CA85A27 +0BB135B72F1D5026E8217581860729E94F2F1878A0E96C59E9F62714FB5F8F25003DFC7347E99007 +8A9A331CB3A6A535BC61866F02513DEB982C4A13ADBFBAC3FF70A7335F40D5489E48E5EDEDEF1619 +1973D932479C62183B0E25EE8C4F76D4F1AE45DAEA4A12AEDD9EF81D248E8D19F8C8A5BECDD1EA1E +98783EB7A38149170851B1942C96C53DE06DEF80913BFC04E539EC67C110498D15B78268853E5C72 +F485F8A27B768569E54241F6115875E2973292CF48FF91D45EBED627AE9F0766D22201B20AFDD40E +5B17CF337F2999E0BD15B86E46EB3C18FC12B7DCADCF9DD50C6C7E3F37E615A892DB3F57E250A072 +A49F7277DD6A2C8042698233D35A699B17ECA5DBDA6D250ED4A16FCC893BF0DC2E33FB1EBD7DEDEA +3C1C39603C8B7E1A5A833A8FCDD5570BD088749BB232615366687962C7E56ED089CD7B092505CAFA +5A80F503C4CF337F07ADF0D106937E25670839D491F7BFF7A523DB609D126328C16113ECBCBF9C40 +04904427A108618AE5D4ED809F8CCAF72251104C94EC5BEE21F91B179D31DBA79CEEE5EC7FF698EB +84AB1D2D1A624F58B3622A78844CE51498B2CEF38EAFE259D22C7BA61104651A862008BC1DDDA58C +C45F663EB26428DAA85E7785363A69D2790996EF5D9621D53042F42F794962FEA46E46F37B8AD1FB +76FC8D5CF2146843F8CC625139C75FB42DDA71A752BAC48F294E4C0C8289FC46DA5EFD9C91BDA6D0 +27518B7E81E8B21F755A9615627D5812ACA674D1527A1185EED4E3C628196E7D0759B1CAE6B9B7E9 +01E9599A65230F1EE469CD33B9BD9C104C44E3C1AB966C9678BD0AD78111A4E0F2D07A01A038CEDE +7036D0534D684A1562A17AD64A00F279200C0371B1CBA61747671D2A21D3F9646CA290F6B82418A9 +6FA177C6278277504B7FBA936325F5FA124AB018A15DC18D2C5E8F93CDEEA52BEEDB78A57828D81A +3E6C38B9FAF3DC4EB7273ECE3EA4482A1C6242A335862C2C3717F9C9ED95F77B140C4E1569B2192F +C7DCF702D0BC9A50428EC406F8BD0CAF886B4D979320D3E429816D88F7C7146D960AC12E70F2CB7A +9F4E3E366665AB3F1B4B6440F55EEA26DC9EE0096BB7763731740A537766490C8C174723BF0EB40C +53701AAD12B21D436ADCE22203C1053A9DC4E9F17AE617888C4B4E6F3A720E4E6366BA628221A387 +D8AB15E04AD69387C310D3528BD2FAA5B22BFF3FA494F5FBFAC4F771C9C7402B95580C5AC4BB3AF6 +92A70CB2C851FA5CF1173EEC3EC29B5A05A0B728BBBB51D3B7AD8B0AF17A1563E82FAFD93F8B7118 +1FB7AFE352874F4EC6D334AB6747519AB8E847B7BCED33EB5458A828E074E74BA621BDCD03FEA604 +7F7B6ABDA01FC7514BA1AFF0D4D0C0CB8F4E42D5A87E395D9ACDD02CCC220C157153422018725846 +009A3ACD8C8CDDB66BC6836B4026FD9F526AA275D06C813179E5924F26A25094E7BDA8BD26AFC4CE +B41D8964D4FC4AF1DFB0595BC5D6714C32F15DC7194E9A3A73013C45D8FA55CC0550A12D9AAE8E9F +F199FA28EFC2426D8D1DEFB93A65717AF3EA8E2D5B4AA8EF0EF38E9600F7D4E7D9F1D67A2E63ECE4 +789FA74B159BFE2F91C19B0378BA52E93DF12830D99553B6618645E26126842AB70262D96E35E5E7 +50ECA0CE3458B3E51BEE2F21191136DFDBCA39BDC07939E521E4F492F392DEBD029C1EA237BD89AF +76BC89F618D530160AB16269FA6B693CF14BDC4EC7C630025703C5337F61458FA09104EB15C7CB20 +AA4C9BDB7CEF3A09F25BC7F3149951A7CD75372993B80CD2112F7674CEFD6AFA764AA3486730D2C1 +897A264D82A91709FEC4A21E30D812F558451804EE6F3DEE2C4C437846BCBDA07C5B6CBA1D94AF02 +9163B7383CAC6E088AB1DC14ED3743EE77E26EA7AD3119A76C0B5F925C4DE305CD7BB3A09A453947 +5B9BD79BE28FC462D8718CE05F9D94CAF3387BA55E6E447BF81A9EDDD3A34E17BE66BC52B0C0BB6F +86F6F008829173816D205182ED2ECED319864A796AB65D4E3950288BADA94FA32B6F453AFDFC6C39 +A4FCFE60353A64627E2057D4B379D3240012B3BB0ED0C7876CB83C1BA5EFB6E2A03F340C2B576731 +F848F762A7E1CCAF267EE06D621BC33FC245D0E1547ADC12CC0EB58B26BABDB8EAE9CBFBAB93836F +FF22BDA1831DD01B7346AD377AA298D84628BF1C07433284B0A90FC89F5AEB2651BA2CEA405D4F52 +DDC0E74B871D43F71EB4ACE0D2B401F9348EAC3A2EF0AD295036BF6CF6F870D58E00B619D50EA7DD +77BC28DEF91D805CD527DCBCFDC16C042BF9B874E3B1567EBA4C1E70744B9E7E5BD1FDA6A5FF6E10 +1613FBE58DC46CFAC1A65ADAF65E49757E9304E2AC9A91E0588600C709A61D4231730073A36D473F +518A145E141D0A5A494441B9EA99AC23F60F54F8127B477E1CE698BB4129B4B1DFEEDF10D9E665C2 +47A62F112F5CA30B0AE5DBF3E495FF06EB28EB438CE8AAAD84D5F50FB56A3AF002C23BCF66ABC270 +7AC233FC0F2723DB99D2CFE7D3B3667732A531F5DC315CE74EDB9050BF75D29E6430F57CB6778B2A +CBD57DFCEF896E6766C8FC5C9F9FBD701CD62CACF33EE0FC95E78DADD205B5F42CC63024624BAA0A +B4DD447832B4E1DBA77BDFADD223989F8E958C8D759AAA37930664C6EFEC708116248A2A7AF3D656 +DDEAFD009B7F5333854608E67E5E588A857167ADF9225CF6C641F5E19C3E08678A281199EDDAC831 +B57223B1BEEADFDCBC8F6F25D32FCA2336C808162E8F381656E847FB6CB13969572425AA05AC830C +33DE6E030F86A3A85D2A66A77F103C7042C97205526DC882EA9A00EB8BD5519847EB424C15F808A9 +1652A6CC89B66A5731126DEBADE123C63D88A2E550FACDEB3886FF98646000C64B3A91078012CA30 +904B71737CEF6BECABD43DD702880538F5A70085E6CC6015D2163681067C3D513A8C66032C34A0FE +17A58AD4BC97CA69BF41F11D5E910FDFE9729652D3EA21F8DD8CC19160A8FC77573B1E9CEF4E790A +79D8AD6723B6804E9616466C935303E063DEE29CAA6C3BAEBF278B818C2EC2F13ED645AB452397BF +00DB8B26E115026E256746CD0C78A959364FDE6DEDDCD0F441A61A1EBA32C7BC172BB09512148D1E +BAC9E791B7D51B71CAD2DC9B83B2F99B3726607D9CBE58B499A13753CE87FCDCE21C0AD0528ED0EF +B9B2C927F57C78C626248AA2B835A0791244C5896686A66173EC9F802C4C633A42B086334D2A4878 +0E53D00809247BE64E529F96AD2F8B3922A6097D414DDE1EC76F9552F9B8D58B8E34F359AD792B2B +E50C26DB05035E7497162E7C49C38D3CD9B98D620AA67492BE5AFCA3A81A7080185C7F0B5105223F +1FA77805502A2E8C5FEEA27699858D84A95842C5F2FB68686D59FE24091FCDDE139B6463BC6C7B1E +0E90D20A83651AF00C85797BB9F53ECEC1675C7EE636D0D9E77DBD8F89670F855EE4D4800FF3F695 +0EFF09BBF8A0DAF6B8242840CFA5BA73BEB95115F4A78BCC02D85ECCE0C0F2EF6F328AD1DD6CC049 +5A3315B414A4D61DA50DA46D7ACCEFF6EE56451805D26B0359AF193531F95F6589CEAD6FA041AF15 +3067F88A0A2FECD135C56682DB2B45A71D1FA737C064EE9A4F404BB72A70B3AF0330359393247EC7 +81512482579865240A23CD8479F21C2C44A119EBC4E81B308DD8AA86E60C3DD8ADA50E0DFE8308EB +1A7F201EDE8DCFDA405AEFB47E0E6CA7DDB376DCB21D37F7ACC4D3E9F26B03A8DE0E8940CA3A9E75 +963A389DF8038D2C486072F61C0CEAF500753C7A6352B1CD0338D9212B42A4D3DA23D5BDF44C27C9 +4B88A415A3242FFE2E1B332477A21D2B9CE075EE479C6E657A4D8874A8C53964229310E01ED4F3C6 +86FEF5258EDF3B464DD6FFD7F1CAF473BBE722D60FB14AB4918E93878A8AE4773930B8CEE110F476 +7F42A52D9304C55BE12846C911A10AB9B2E036BF9DFD597F5348D42233315FA80D0F563C388BC253 +2103F05E90DBF1923F229F980A2F4585C7A373511372D07DCBACA583099EA972C03E5AA67E663882 +6DB134564DB993CEEB6E7A6659C7C5C05C310267D5F8A24EEC2D5CC3E3F3C808E6D6068D1A57646B +37FABD98ECB7BAF99E7D9AC4414A491A73CA34C52F394352F6B5A15F0FC4D88622DAC694699C2464 +84ADAC3B1D366AFEDE2A2CD2042C90516A666A19A91C80248B11224BEDDF1A320E230739E755D098 +B6A67315535F4C187CFA67ED817A035056353FC859BF286317996FFFB478A2248B908FF12ABDE705 +402224A3EE5F463DD3D243875C84E02DB968ECA1CC52C75171EA50D6A88CA91327A7AA5795019F36 +C0A19C093A1C9D3723C7568F9D41F2E4FFB712FD47F897703D7A620B586B81936C84AAED61D84332 +B3BEBC4F95B796B93EF7A1F565C494F8A65EDB21E2EE18DC025522EF8E599887CA2836069CDDD889 +88E5862977B7472584303198CCE97EF9F9E1446D1F1F5ED1CFC666A8A0C3A03E1792EFB60A9B4065 +49E0DEDF6ACCDBD98742568B4735A747D8E5DE21E630125AE0C691D054E42199C15B1F80CAFA6E7B +B2005F374A9A5F9900ABB7409CCD50C3AFCCAB1214E6A856F7C7EBA89BC3291801E1343DA9DAD2C6 +ED075C8ECA1423B43E587AEC67E6145272814B3F191B3C285639F9E2D6E148A02DC2CBC0E054D629 +5CD05DBAC1950400A9189316F0265B86A732D302C5BEE8ED233768F237C62600CBAAFF3A110D5EFB +6CC7CA3B92D965CA7C5E8D3E64ECF239FE2507FC797FDBE54C1112B28D4DA44C60AB09D994C5BA78 +D663A2591934CC052BC70CD1DCA3325C66C9CB982E2039F5DB70C848D3DCEF655B1C2CD0CEC8865F +E8E1C0A267BE4F707ECE6F5A3DFCA3CC1EDF92C760439F51AA69A4C1801E96CA4D6EA4AD980258F3 +D15C893913ABCE09101984C61B91D603053E49A97CB82FBA707DAE8AF1D579FD69C8481CB7B712CB +CDDB4D287BE995E32C02B399602A08B9DD849039B5673F1930BEC7BF366EB082D2CA5DB2385C8CC4 +5BE3FC0E31820191A814EBA7C4F23B1938E6C4D800732787CD2CB97F762DFC85D4B798809B5F2254 +D826CA42B32695428D120298B44CF38494E56240B75DF1E41E46E53C44DC505452256DFEC819408D +605FF14D6C1F3F152F2FEA96EA0AB3B472D8704E06BE9F8C3E8395CAADD06D6DA033E81ADE5DC3B8 +3DAFF743C6E9E48716003D358DF63CD7FD3E2F727D1F2D0C29962F76D5C95ED44B6F08D052025A66 +5785F264A3D5F5593677B630E628B5EA81FB37CFFD7A30B7FAD226B6FDC82B0878AF4C0EC4F4243A +807B9839EA62BCBDF7C2E9B30A623876E632E084EBF4A21EDA04FC88A1C07021D0C72EC3E969D449 +FEB08E5826EC20E55B21EA71EA59F6E3B0710B0DDAB3261B4A2029ECAB68C19ADD5174E55D5E984A +4E5F38F592A302FEE6ECE732DDE841A28672C620CC5D687455A5C06FA9FE688394A04F96312ED025 +B7AA6FBCE2925F3AE559CC1886BEECDB70822E2E5CA3F732A87404B1536AAC469989E9610CFA440A +CE43875A70CA51F36CB6F629D9424C1E35A88F92D5DA3CD8CBAE6E8425A36968E21F4F30349749E0 +205BFF8D552837D6FC39532525370BBAC833F75F1854C93FC533A4AA53ADF7008173A70D94A4EBF5 +38EA9E62BCDA7C20E0A073BEE2EFAC34D2EF1D03BABD5147659E50B557045B2EB89DB303749B04D3 +F54B43FED612FCC68206E001A7AFE90230D9C12F74A32C7EDB5D0241DC3A5D51481FD7C8FAE08FEE +263FBCED7C7D911B3A303C835AF5FADFD218F61A9D6DE80485ABCA88200047B094441F7767B97A24 +E8C612590FA2407BAB1E8B56C71914EEF2355DD97CFAFCC192BC06FCE063D3D9D1A629AADC75E3BF +207234C208E7E30663EDD691043065C9CBC473D97C6D4DD3DFF59D6A9ABCDD4412C3128F603160AA +D8F81C6E7A4DCAF35F3A99B4EA10A34375B477C2BF846521A7EABD4D28078E9340452A198F3F5ACC +3DB7E3908939FF6E3709C6A3FD9889439A4AE3E10B618CC92E14B68429A3AD2C80940A1079452EC2 +66F254657BE7D79A2A24084AF73F6DF71FBCD32BF6913A3FAB25F977787F7BB0C3A3E8BAB38D7A2D +B0B4826950643DD1E03BD7DD1FB149A33862A89226B7CB454DAF613128C2075470E42E70A9444A8E +6ECA526345AB48E6F5160BA23B5BDDFDA6049EC44ED1461C7E0DD514B16E2FB285F72039DE3C7982 +EFD40D7F6C8E8F4CF35AC71B467BFC578002E8D2239A2FD2C4BCCDD8AF3D7DB1F4AE7F2D2E0811DF +9D0155BA6EDE50B5F052F14F6AB884FFF244D8806C07EBCB49ED22D85DF696995991A954AA97A1EC +D86ACD76E061B7541E87997FEF0657A826BD88EF3A4A5920462C6595E7A156F453291CA044CED810 +860C3B0149BCE73BECA713040664AD0591304106129600AF71317B0D2907839CEAC99515D357E980 +B1937B6E1200AACADA205421001F1B2F91753E80D2263C56AA164A74701A8D5FD28E46480B0DD963 +A683A1F355D7FB4463C7347C94EA5E2CA40B60B56297CB22D972C5BB10E56715A955605256C1541D +9F3BC5768A6F355CD3B863F0FA1A781EDB49368F51B29481CBB41D4AEB07AF9DBE8F52C5D0FF75F7 +FB6431D37D6AED84D78C778871CB0F715B4F07580F23B586C969C81B471FF6A6C7276F7E141E02A8 +584D4B9AB00E7BD643D2C3FAAA299B1F1E25048461952EA42D4882768A70DE46B213A287F8D31AC4 +6D5436F22A796C05D1FE50A9BC2A928066627A0D87DD57A3AD91DB446404B41557D1457873482005 +EA20916BBE46C613F456C849D46BA79D20627B446B2F49E3FA309AE14F8C420CFD94922CBC0FB9D3 +5A0F7DBEF577F1849A1A80E0011DA8AC082A8C6F61658E65AD177ABDF23EE17C8CF0D26B9FA3A6E9 +4837EB9E930336889767A8D7EA3CE980A8EA95528B004957BE6067CD9BD8E02A0F23CC1762CCA656 +D33412FF45E917FD4A03EB6E8C1F43FDB0A8965A33B4FD26BC24A20B304CA817E88495BA9B361A3E +933717FFB0271F7F70C5D3CBA1E86D0F51BF3ABA194DAF32C35C796627D00C7B2271ACE2463E37E9 +7B3C826CF3DB60028F240F9452CBE08F7EBCC5FDB1BCBB3C327A9F450B9E5671916101D6E3E5E458 +CA31F04D12F592F83BADA2C3683D3886AA3B403963AB5DBE220FEC00037A745839F67A3635DFD3BF +F08F367482962DED88ECF6322852D643A54D5D303EB04BFDDEE9BBA1EBCCBA7C653B3A613A8E719A +DEBE3CE1BD7E754E5F4977E863E3C2D388A65227B451D4F3A4F94E06513CBA4AC1F2F511613FF035 +611684CCC461599000E546E4D972CA6960E095A526E4735A23421A4C9B597ECE08AFA2753592BD16 +DED93255A1E33DEECE3C5EB77B94670E8137F2A4A4B98AC193258E7DEA5DB8408A806188F2D1DDC4 +40CCF0E9A6E2F0C78FDBD7B68DD4939D2458C1965BF8BED4564B32462FFF3EC892C03B11D3EA813F +AB4CFBE8D3016329C5B7E3DFED0F08284D44AA0B7A2F6BC96EA4503E8EF52A64C22BED6B452581AE +8FF8917D53976471941A9116A2D878FB2541B561767ABD4E31CCD8A590CA03494C62AFFD64EA0A1B +C779173DAD84999C7A8D844EB1259DE7BB5B25CD023537A474A524EBE4660B22568949E624D8FEA0 +AD37F4CE1EC75955EEFA49C6BF1803BE87E9C9865FF3F6B8525B8C15FE8835CA153D27E6C0FF0CA5 +1029A7A9185D25F0F14D86FC797DCC1F99EE97E2054B9C2A2E06FDBEB8DEF6CDD368BF23A858D9F8 +C1DEFDCEAF1B4A8DE5EAFC604CECCF0D285BE00AA912EAB66EFF4D37AD2EFE34853BBFD87CE09B18 +749B489943EECAE7887B006FB827D10191DAD18466CD1F86505879310A8B171F902EA0C26A388E13 +B53C700272CEE2BFB47ACB58247C13449C6BB9D01232C32517358F1A3DE064D43C18F8827D53789C +CF3CE2EBE78949A6ABFA1A6B8414CE360A5E22AFB7D1DCE6F5A06182C3B984B4F9BB1A905A9D5A14 +83750A1DE0A857CD5C06945EB7D4A2A6BF1237F32A154FDC06D51A703D44FE052FD3C53E9E8F417B +35D1C851F9203A8997521529F21AD8498F96930AA77EBAF82EE02A57BC77C792D9F220294B45F48E +A8FD94E01CD25645D36D168923562F3FDC93CB79DD4760DA0C103C2675722D7A1B79FCB4245ED12F +A0DB52492C9CCE58B333CFEE822812F7DCA68E802C451B5CFAEBAC608B950386B6C58239D1C62D62 +4DD5D15782FC552222CCA06DDF387B373E32C3C2864C63C768350C37283760F3515A5B0AFD66C48A +B522EB3E808C061F5CD6BD96CD18C9839D30508E7D4EDB88E8F11E31E10919B16B7971F06D7877A0 +58D8A4944C84FC6CAEDF3341B48B6E0D3C7B85D710E0C35F5B5053CF4B4798B3778CC28B2DC7AE0D +F3A49F9F3BCD8E95D746C35C3F47D68B8AA35D97AA08E711B5FBE70D1A623C82541EBDC51A827D0A +69E6C049087AD26F256EB7577F58CCFFBCCBA5A95D093DC29464C9A38DE95BC6B1853963B2DEB0B5 +7AD1248D6F1625E115EEB9510B5772AAE4E3C866657DB0B3BF0E0AC345E116F8D4976B770876FFE3 +748C36165522991F46A36F193DD1A1C94713673C7E4C81582391B636C72DE94CE6254374F99B623E +5686C13D8A8322E83E11BB0B0A896C6A8C2C4F756C5385CD7017F26D23F7C3EE97372C868C8C9155 +81723BB6B76B4C3CE8998E4FA6CA40B633DFDAA59BA902A4952DA90EC4FC3CF0F2676ACFA7F76F78 +236FA2DE10FD3545357215246BB7E527F277C28B353CC6D79DCEF21BCC8F77603CDD58A2CCDDBE3A +9802F941CED8E035313875319548C41992A2BE939A17CC109426E33825AE59BCD17CB19F50D972FF +CBE7D9B4B0BB095303D9DC9D406696C2508D6CE99E11CF00F6461147E97449ED5F486D480A86D3A7 +ACECB7E9A945984724EFC21C5079B1FD03ED803C2DEAFCE3327D2D7827715FD65D9506216C88B0FA +26935E95C64114A51919D419038B1A7E9C1E829FBFB53275093752DF19891A97F3CBF7719C1FD6CB +17019A6D2D25360ECA804C4B35172662CC4769D2B785C6C87E5A4ECCE31704E59F71263B7C3CAEC8 +ACB4C7426EC25F11A0042323EE6C3EEB04284DBAE2C770BC419DCE79BD4560AEA41571C3B595F525 +60191DC7A8FBF63D413A77A0905E517441B16C2B501EA2F9E99CC38D052679F288FDF1894542E3A6 +6989A0090185EB2E75134BFA3D9147C3DB8A621D9D35E37786853779E157B47F71626D6B3E633005 +9159C17596C1B87FE2B4FF47ED9D78FA4C2160077276C8B58CEF5DC030B4A5D83CF257096C047FE6 +4DE307C598B815058E72D5F57DF5C369E664E137DE29349E2F9DCD8C9F4EBA6E765B6327D7A20DFC +B20711273FD8091CBA605C4C494248076F7E03DF65A6A50164980BBBB708741E5BF6056E6F996DC0 +7FFF408C5B8EAB8DCEC315E92873228C805D4440A6470E3EE3983758DD211C9CECDBFAA4C9300CBA +00608A4B2404A3C7AF017A3B7E67F39F0B51ACF950D3E75CC7BC2B8D3480202FA958E8EE0B240501 +5232EE0D264C7CA02C18CA45CB3C2DE322D3EB7F00F9455DB6C5B1F4E59C3E95520EC36D7D903CBB +625D70B54BF6F8255E412604BBB29FEE026CC660577F91DB1DB4A613EEEFB20CF7AE3CD89D565AC8 +38416B01B5DE4FFA5550D17FB51FBBEBE21CF1D56038863EE931B90DEC2E211ED42BA92EC244D4CE +2C4EC5CA87A026992772DC2AF754FC982B94F36EA7B7BF75E0ECE90CBB2A6AA1A012E8898BD679C2 +3CB3827C35D5D02F0569C7AA82615D4AA67518ECF668D3B57D6EF1A8013424AC2268BA0D9A74D588 +79EDCF6382A89D397864940303EAEC45A38304BA8B1CB198967AE23EB81054BE74B16909A405E8A7 +799CEE3C270FE2A6DC50BD7370B6B2C8FDB9A87D88D5D40348D3984E39C693B6F4486D994778607A +80A3122872DD65E40492107C71C3CF708A9717E9EEFAFBDDC239C53AA9645B711038E59C8B861B37 +411AB2039BEDF9CFD00F08D9C5D76154427FF5DD39878CECC5D7BFB3F1F035087185C0981F3C2139 +BE84872FFAD3408531C4EA9387B89F5E3EC779E8850D50992DFDCF9132BC551E985943B07618AC10 +D1150451F0844C0DC41D6E17EB508DC8689EC726400D5A7F6FEB3CC7BCE05F09228B7CB2C5393664 +D8DD9A4B96B1020EF25D70AA2D91CAE93AFB5F2BF0AA18CA5C599FA1A708EF35BF8F7FFEC9AFC1F2 +42870D028B2B1459063B493943EF1283829783E1010242E5CF4DA39D93D506F3892936E7D6CF1124 +70A521D397438733D053944CFF12D6FFAE8246F20618684F263715AA98E15D72A526383E05C23214 +B78338E5B476F0981D90056E6E5D0DB66B1DF2298E597B2ABE1D817E18BEB056E65EDB4234342D96 +00470B1420C9210419D834E431B82F58608C87AC361A02D0F1FE4B470A3D71E0D21BB87E1023D428 +E23D596CB9E1A2184403A16E36E644BCCF9BBDE27290485057E62827283E7380AF786BF395B3961B +A5EA469C315763FA59E0F176EF81985F38B882DE56A74D128E256D1B89939728E55A92ABA21A6B78 +44FAC1BA7BBDD8B34A18194A2984B000380FE9F672E83EFDBF276FE797A325815B0F25CC95C97A9D +ACF56D583486305D7C9E51A7E337D14E3B900333EB38FD93A99587DA2341B10C059C71CE080FE753 +3C0F059FA40E560AF9C4A41A4BE6FB45846FF8F78165E10B4AD40F264BCF5596A1E8EF8CB6EA4B1A +3A5C69059AB1563843679ECB2511A90E8898F54295649CB73D277760D8D04ABACC7BCC6E777A0530 +E2067CCBC08673F9C8C178F9D672AC8A15E5367F0C5651B53E75E0CFA57C931746AE1A679C246D7C +9417F1CD89DDDBD1173C2F880B7B3847CBCCEBF99F7122E832D7C9BAFE2B54CBAA1ED48158DE3F36 +238B76B0E67644A28AEA996DDC006F6AC0242E4B667639E7523CBC90A0561193C1AF34481C2EF402 +EE43A82E1EBF4E3D601BB36B2D95CD93550D61CEE7A94E72F6D30C32C8F91A61E964B1F66ACFC398 +7F95D4028F116E9A9A8474AA29C1C1A984BE0E393BDC41DCEF6A6F1018DB60D52024899D8EB5D55D +324D73F39BFA47377B9E15B3B06A7585589FCF52A54684173E5183367E7B0952DC4BC2767C4C6247 +B1D6103E52BC7B7EA6298F454C5D97AC575F19C10ACDFF4E10C7D3755CFAB4200CAC545269FF1D8D +B0D607C7AD47F40DDF257AB4E7D0750577003C13E4941960C3DD7B0774DDAC18E8ABAF8F53E03CBE +F6D57B44F24CF821014C064278FD51B3427593D17694B4ABCE81F49CBB984C5878CDF0C38D1ED7FD +99B0B9A3BD8D8FF6219588B3B8FA59D0CDD1D9B2F65122AB45E48F1757467B9204926140E3C350C5 +A927A2E700173053EC35D3F1DA2D7258714C97FAA857F0898917BD94625C6D1E2D77138EFCAAAF51 +7B17FE187A2212C24A881A2C6A647DEF6376ED80AE4175C5EE80921F001995B44E49F0D33DD9075A +CF33BB03671C0BCC34AD5784AD1CDFED3A6D9BA103B3DDC1CC2DE74DBB576A0277715275218CD19C +A8899209125266D8BF1286F881DCC2C383749D1E768D670F4099F7DE959EDFE852583183C9111601 +2881A56A24AAF020EA45CD5F39660DEBCE30AC1C7B8CFC60387B1B0C3E361BE612FDFA9F01B7E4B4 +A18839A2C7E0E393EBC5AD9A8A4EBC316A740C1C295D9EF5F4DFFA0667F9582C0BB837B142C4CFC6 +B1798E9476D0631111033B8BA75A10FDC800E2AB1E0E829632F869CFE4737BE9E2800759EE0831DC +7D1195EAF80555771981DD6DC6606812D92CB8EF86447F5F6C6F626D0E265C67E52A6319189EE349 +D48E49DFE6A9E98F76C414A1E3217AE0A215A17E54AA498F4ECDC50242ACC7E2322F63BB2FF2189D +057E7354E32A3ED1803116176B9B9D0129930F919E2FEC280B2C8924E49E7BB75768A2EE1DA8ADBE +D4E3589906DF1B923AEF84C1BD327438B731012E69BB0D43A1842CB88BB54EA4516477F704CFEB28 +6E3EA483445AD4D74586FCF32E96D366901084365F693A53C5FB532FBFE7BC0CADC404C4985042D6 +8DBB90A6DCDA3531EE324D558A214F935CD9FCC9A0CEBE9B5FB0323F4B3820529599EF48EE068B5A +CE85004FEA2984F0A86F5AC9D56163BBFE1142B774148F1EB0A4DC89C3349052533A7DE66729DB24 +41B82F8F7360111DACF69293C9B281A0534F3E9E9224A75C49A832F28B2E497262475507B6DDFA9F +01CA0A6696E3F5AC7EA68595EBA0C2EB8A47813FF936D84AC1B23ECA7AA2862B793CCBB0DF9FDD49 +31BEF354CEC12FBF478559FEC29F81ADF4452E83963E56541D31F3691C93A50F0BBA5E9552C4F2A2 +3A6E53060729854A3DD71CC4308B91957DB19E66AAA18FA67055A950F1C2CFF78A03BC1A588CF624 +696068068719AFB1001C4581EE072113882D9052B21E355D401ED8CD24D067B99E616BDA5A0A5A93 +36FC499632B79FF2FD0DEFB096EF46B75E2D4E0F48DAEA239719FEC4D9A29818F5875FC5041A9EDB +D26CAF0ACE14CC80BA49BBA59E918EB3D8F1E541AA16026585A2F72DF7D83541816DE46981FB3EFD +0C30E458CFAD04C79421AB7C4925E23AEA07F9F018431C790002596D26BD9663B51B699DF53E4882 +CBC34EDE88EB55045B889B6062E35FD1E018BCE785157B85EC3B9CA6C85D4B16238275385B8285DB +012D8FB7C9F5B946A41D7A0FB878FF72C39683144D8A007CFF631B43748F2D5FC690300F9BC0C837 +006B92ECEBE0605E8C3A4A400E18AE8997D1B45FEE10068E247C647CF82C6DFBE5E881D511FFA687 +B7AEB78546BFD07D5F7EC242DCEF4930D8AAAD8C6152B6642AAC325963FD147F236BB850A9966573 +9D06CDBD7CA79A527DCF461E33F22BC9C5DB00DA2BD3DDDD8C99D99793BC98282AA8872FF96C3942 +85D82D9419EB78B6AE37A5F519397700F75D624A09BD255B576E955A323E784E8FC31131F003B0E3 +024A4F58FEF2A6C043796201FC425482E1155E229D1B2D43EF7B0D22322B22EF5C9A1BE026A1C3D3 +75EDAFF99597E1E5477952A4E8D2ACF5D014BC00DC2A272FA62B6983E27D228881E2EF2B8B95A681 +CBE90C5FDE16331C85222FE2A16F0A3C3000A63E2E21666C0C119F8AF89A543D37977069A5ACF155 +6324F05204CE8CAD50FF4FB630D9CBBFC324DEDA584AA56A99D3A76FF55BDC2C2EA3A021361CCD4A +83C7A5E2768D210FA6DE889FD48A39D679C94EC3C99A8D33FF11377DA7F6F1B71A2A05B302ECDE95 +4F26773F39AC881542F0D0969C3995C3519A8EF70B4220D86BF01BEECC6462855E7B686E1AFF1CA9 +1FB8FD8B4A69E10EE0C2AD94ADD44449506F9B6EF43641F2026EFF6E605C670560C2B74706FB949A +A7E8CC6A2D0D6207E457E7FD87EC1B9092DC68B9143947CC8ED14AFDDCBF8FDDA228A76847F96802 +E561F67CEEFDE45AE587673983FC04C96744DBAA83F2DC838D633943C75DCB9E6410474EB27B348F +26E505F0AB90878940E846C5E9F3C5FE8C3558C3236B1B88C405716949B8506841CABE1717474BB7 +C30DB91CDEE33B0F844811762FAEC535BDCF84C1C747CEF9B1FA61D2AFB5A81335BC42C06A94D7D5 +9B7EDE55BCF6F9867AEE107555CDD084B7684C2C87087475A39A9DA6347BE281CE5635A4D07865BA +98CE26C1465B1AB0343F49FF37B4D0CA9F3BB693D78DC3B21925CB996A038DCC172527FE57C07460 +EF39C07D4396E7FA970D9F22ABD21A9C794B64AD96762C7428F59A8757C36D6C4FFB23216195A04C +2A2C2E7B10EF7193931544D782FEE4B91E01119C5553BBC6252270A8D8C56DD62D448F5AD8DC69CC +B45E1F17F0AA1E445129DD00F000005B23D38DE93A3BE55A4C041947F36B4E4536E307D0180553F9 +2E46B743881CB5D5386C48C7D5F84C2BCD06B9C501F78C7EE61FA23516791FCF4DB278AF688A2E60 +10A56692AD92008497487EDFE4BD5FA083FA544138B20D6940020887E35D46E093B71F7A04A67460 +DC8116B4D4839625D7CA6959D6831CD93F81AC4EA2709036DD738364FDE71113BF22EBF13DFE1642 +E564701E6F0FFE7511EDF03FE448C2B28C64FB7D54B94CA576E481FA56B2B18AF10C71F699B6BFD4 +7459CDE1869D0FD306BF489A6F42E5B2F05CCF55BB6B9526973D19CB134CA7F13F1DB3716F8CC217 +73A832568C16250B5CDB16DF24BF81D49F5B37018BD310262EA7078107868AB0216CEC83CEFCAB1E +9F2C665A31585CA04DC01879CAA79AAA5AB201B516F7052B01B16BEE5606098393B0E5D9F9E5E3F4 +EB20F63C958E796DF41CF28839F5C62A0431648745D7837B519F3AA36BC6C08EF040CCF53D9B6D8C +0C7D1A84D707EC57A3C6AC9A62AB37251A01A5ED40FDEC6F5BE6E34C6A91D058319439778A2EE5D0 +363E2E1F33463C33327D05FFC0CBF08D5BC457C7230448972FB9B4D0D782BA7DBF10D3FFEF8BF523 +6EC16D4DD6D0D870D9D5EB5C64C9A46A4F583D4F831FEE74B0E5B33A09ABFD4444929BD8F638CD72 +EAB99CF2E9551DF427683964A592E49D186F285258C5D5F62196A98532421D73E3495F82695FEEC6 +E1952C562D546B28618FFAEEBEFF03A57F4D855021F85B0C7BC37FCC6DA9AECA099B646B99D41896 +09D3FF2D56422F8C37E97640293EC7C90E3380887836F4938FBF495CAC14FBA5648D89282D8D49D9 +1AF73ED36581139D8BD42551E263E830EA3C6EB381D85C42D74C50DB0CCAEC03F535ADE92128A016 +0E811C34748309AF7604919B66CD43EB5CA975302DCB6076FEB6BDD6FF55976FE990FB0CE9ABB11B +195403FB26E3D6C6A0DE1C5BE79E171A61E21F79EE8DBE7A832519813EF6B33EA098C2C32ADEA219 +AB2AAC8B093F40000995539D1276D5F2EF84CCD099B71FE4269BDBDB6A8D59C86F7D2E3FBCCF8773 +D0FAE97640BC1AD43CB4B992BFADFB09DBD0CAAEB8CD9DA264187C4F97300E9A6C9DEED5525479E6 +05C65AE336CBBDF4E5D7F79AD098F977285E065579B748FEAA97F2A753E1F962FCAB68D72BAA8EE4 +FF6691C23E31BC0F3E981A96FB440404856AE1AB32A7205B17D411D8F21C8C93B704D07EC594422A +BC368CDA2B1610CE6A973F4474E12B78B532666797F5755D269772C9F5400B3BFC6C58395D38527E +2CCCF29B56123F7DCEF3BDE5DC1DFC5B0293BB125085B1D2D929BC3EE84F4FAD571A4991C3DEE03F +2DB3A3097E52B1A7D5C73CCB6148EAC62E8E36DE9A71C57638C6E4D5D9DED18174E8C390E50B4A5B +913C074EEAEBE390B214B3A68F02862B9A296DB4B409769649E51D738CBBDFB7702E15C73C2AFC6B +C37CE15171F4E822CF20EFE55D9F061AA43E648989628FF79E65932390CBB15D8E621333B18B11C3 +BDF96F841D7434E01AD501FEA964A75B248A35CD9DF9A37E48A1E5A09C624B93CE44F0042FA00D7F +9EE89B9F7AB785E9C718CF6E7228F743271C2C9BBA17E5208B920E44E765D99D86650EB454B0FAAA +112753AA1BD3A24239E9C5FC47EEB1547AC9D23731B8DC48B9707830DAEC60C8D3790BBA1120F776 +4EFAC542CFFBCD5C05F9510B27B2534B704ECD36C8B041FD49A96881302FFF5B0163A2DD09C751D6 +D6AFEA9170A4F4C4AB8D46E62F763FE1BDA51DD1CE4A27E772F3A2869155F762FF26B7AA6FCFA4F1 +292E56F03AAB6322BF867E7710C34D43B5D85B45AA68014AD7879EED051B1933E491496E3E26D9AA +8B80A07BF2B94F1077E84A9726F08199887D66DE7A307BF33C30DD9CF3DA188088C03B2BAD09A217 +6B110DB2C868B53DA9A66C85737BA66C93C58A259860E294AD0191E3A72C73F40B0BD98699AA08DA +F03587B78F391F3A4313C58D9F29B53C70785637BD0C58310109C54091AB0A34CBB0C478613A7AC0 +FB8F0A8B4645AC966395D8BA775262CD291136AFFDDF01C1D83DD4EB3B59CCAD18057FE7D92A8CD4 +A58F22508D9FD7CF356571F701BBB23E749BDDCBF8A317FDA0AEFD952BB18545610FFAD3AC143D35 +1B8DB3F66293375E0E50235F0D0466932181D377EDD32A5F0FFA4E22B5A0CB4F343D9A7E4A342E9D +09DFF6C697630CD3971802C277A5590B8CA94BDE6B38446C794D072BBCCB724D5BC208EEF1B018D7 +39373BB910D668882CAA779C2D686081DE6A2606417B54D7C20E0E7F722648D893E4EDBAE8F00D6A +6DA3712F91AE860C756D1127D133AB828E9D80023B50B162C5A1C5CDF70CCB3FDD7EA060ED20838B +E1E50C4094C9E79E1A0187CDF780CAF45A725964F004253E034C5BE46BBF89D94631F1A33BAA35B8 +4FA2A9D08481C6674126CD96ED05DCE48BDA069D902D6836D5DFBA701DC0F98A863E64F0E312145D +8DC0B77F25B43AEC729A1243B45B08CA228DD6101CAA2AC5ADCC8EFF84A4CA3F254176C2CC711EE6 +C273835D0FD3528ECA2A976B88E51FE347FDB60F32370B66D338931D6581630ED586F349C638960C +31AE4204E89521A96E1219E696B913DEB2AAB7A3B022D06F34FDFCB810A04E60A4FEBE284C2F063E +0AE9EDF87704921CCFA193BDC912B747E13570066223A49F1F6E2AF0D4D65DA04CA876FF7A462FFC +9C0BA2CC545C3BD36DBE762F32B2D6BE5867C59F479195C92440DC165098B74EA5C3AD93CDF2D410 +B04C16BC7801E7956F4E5107450787AA592493171C3628E6B8F49D4F8429EB98DC52EF025F001387 +BC1A7093F7A99F10B5D2D7DD8BBB393BF6E56F08F4F7FA1A343F220D5A1EAE7168C74D41BE1DC1A8 +3BD65B72B982F4F7B34F24F97F9EC9A91011064031FACFF2A14921A32024385F4E061CD07D152E74 +1BF97156D951A342488FA7F5EF934CCAD13E2753A0AB7A1F565C2F7F6B349DF03BBC25BBD972A9AD +F809BB5C5048A8CCEF9297B2ED3324D18867F293CC66E88B3A39D107B610DFE79A3B4E83A96D3D52 +A17FE8A62C9FDD271130148366942C9CE57558D023DA5F7501319EBFA33DE9E6D1E76D7C20DB8A09 +B657839DA99F3D8143F1EE6253A3295C9651FA4366547893C2DC7ABCBF4BB7609DE5D001E0A36D9F +FBE01F7D0903B3208AE8547E2E5F14EC1AF4C2535CA8F4EA37E3F3CE172C7A1E8308995B1CC23E6E +81190246BCAB6E755BF868D449BB02A2AA87C44C9CC0F571ADC72547CEECBE104BB274B8AC16DCB7 +5D5F458D356466B921ACDEEAE384E2EB1DF6EF393B41B9747F0A4FAEB4AF1928D9AD6FB7E06FDC62 +1E4C6FC98CFB43F88584BD55D9B97CC9549093EDE586912161931162B1B1D52D0443260DABA02AF2 +B4432100D5506546013DA703573FA8013685CC798CE501960093DED713FFCCF89CA2B9106390198C +29A00864108CDCC1984A8BAB53919028C01B26ECC7925E38CBE6CCA8978EE21C2B06E7B3E48FBA97 +8E2A7D186E563C088F84AA23178B60E4729EE87D67B1091F3B6973676C1CBFE6530EB773C62E2C24 +97014AB0E8B71A1F4E86A378AA26591511BEE3CF3D64C94848582E1354E1605B6457823F2C5E640A +D3802946BB2E7E8E594E8C04B430C2385DD40746CE8534F50842E74D7115F3DB0C72D1C9C607C657 +3B094AEB73B7A79876CFFC3E2F8C9FEAAA07D3BFCE05B61F7749A8793BE90CCCECA2D7077F25E899 +D3331FE161A7E86C842495D584C6E4A0880B2951D8A13B88C4672080A0B1BE36BF47C3ACE7288CFE +41A8C1BAA6F0814A947FBD6B3AA72B6C73A8C578CA51CCC96F2352316C467BB960E981F2B6485BFB +44B577E71EFDA16E7405954BC7C9F0759F5A9F1EBCD2FA9CC9648D5831A68887F41B15081A204C24 +B4B992A231DEF9E698D4C3A25B6F5474F5BE6A601F2D337A58A0D21FF37FD91EB86D1D738893A03A +69F0CD743F611CDFFE69DB2C6ED0E4611D56F803BB0DC06E7FE85A303839612707647B1BE9FAF8D6 +84122CA9E5CB8BDE2936D3F4FF254D31529D7538BBD4D35539489F9E7316F24214B996BCDCF1818E +749A71CF0E8845AA1E2A58AA62A48E02BA4564625D20AA220EE719608521D7D7A7FCA0BD8904A401 +9819D371F3F59D46C1354E5FC1A6E5F79B20CF4ACA2BF0F2DE73DA193A6F9ACBFE0B4731C4BCEBE6 +D96FE822965DE965232282A3A130361F188B3AABDA95A8A2790D9240BE008B6A6DE4BBFCADA05B67 +86B9BB8E0DFA0C30043A3B07ED46277E07B9808422C8ED16758B9C396F4EA929D769785B2C9568E5 +70A83B989B25CE200F1727D41E2B702E7F88F1784F4C83FA60A74EB26B2DA95126E508ED519A61CC +151DB6804F61826C5F86D8FA89D06E526FED97A0DB88EDB432FF32C1ACC9B622EEDF601081AF7B96 +3C9CFC1D13E4A9C74FEA0A1C8E3D8653CD92A944D4CA6B0D306619AFD503506D77732D6514F604BE +4610C2560931BDE0B40939BC1D126B0E97F72AE1B4A9252123B54F7A27E0CFA4425B4546526FD741 +CA77952B10D13E0AC2E32006A903808FF0CD013F936238C74CC75FD915244C56A8412F37F0134840 +347699508D6F3D7F3203A25B7C70100719582CD588590EE34B3AB13E255B613A6D00386A0104CC5E +D2C646F09A88888D3751651D5646C5227A3C80E8DA1B0A331121DD2429F1F4775D30564DFF47D01B +BE2C6C72CE4D1FD9A2077C04D2B0274B8916F6A9D1A4A6964A534F47CF241D5A8E34B23F85BE9ACF +FC2FEA961F277539F215F8728D6788F67BEAF45502839BCF23D8763C3949352F00C579A9A4FC408E +C625E310DAE61512DFE6844E82D36A2F81709E1F05B38AE9C222ED62C961EE63593CED7AAF73CE2E +D3667740C77B309B93EEFE1B4BA65D48575A66BE86743DC9E5D3C2FF418D11F7F211B86E827EE1DF +C3613E7498030F07050524536D1F8A94DDB6698BE7B963C55CB3F74B676CD815A7B3DF4B1A0EA2BE +1B0B9A11FFBFD5B1FA49668AEE14629316AF436A0821C20BEEF7B3480847934A99F6D85B68F4DDF8 +859A754E009428AF89A90D1852C220A607FF0806E8080726EDC94D691D214B4521C147C4273AEBDD +BB4A697EF16448CD9B2FC95293305858DECFD406B89B9F3FDAE2AC579E80CF321EBAE5701FB2F7CA +D8ED04B4A63115886D45D6120F69AEF1A21D80AD3C2D35D2899F1902242B96CD349E0AAADA40F7A1 +1282B6B52BDD97708E58DC5E2D22D1153E5FA3F3B300BCDFAF98DEC2F4E3C82A1C85F985735F3987 +4F557579F422664E07CBE19DA680EFB0FC82C323EC5C4644C51709AC8D674608A8043C91E6C7988D +430F10BA6CE1FC7FC0604FCD8F723895250AEC36CC35B3FA14FE2A0D24095DCC30B2093F2298F5F0 +A97676A0BE66C3DC9ADACFE2FC0F721A20E945AFC1096A619075D5E9A264C796EC6C90EF1AEEA8DC +089B44FFC13D27CB2370070A52D4416C53F364393E46EDD7EDE00799960CE6E0D57E4909E88ADD64 +BDD2B0EBE2D73FA6ACF8B40280DAA0637E705C65AABD523B8815F22F23E9FF81E7829C7E4BC980C9 +143AEBE1A04DC0D253396BBB7268BD5AEEA356B610D5DCEE03135E00AE34388251F31714A1C40E18 +2652C48CDA2211A22CB6F02490E69A44CECB169754C53B16028D352E0119F5D5FAE0BD7EA1CDA647 +12A6147374B64244E21E9EC9F0D1381AD22D5B6212B26C3F9AA5F6045F25DD9F5EB4489EA39B1945 +331AC70510C5752557DE21D0A6CFC1EB10A98FA867B76DA6E4249469F591FD154D39E89364A43DB0 +07AA0D7A911CFAE6CE2B557997FBC44F55A27F622BD7B8B10EC9F5D10F2649A646FD964AE1B111B3 +5B46A252C4DEE44E7426EB5739F24E8A390694597DB3A1FE7800C97E59558322F0E49A0CCE2AD94B +1E2D1026AFA771723E3F523916F55ED866C9FB4A2F759651C613A2CFF362028CDF9D38F05D4C7C60 +24C533E930B64B099FB1AF04B01F5FB9CA6867E6EFF55A772C5391831059987E10CBF987E3F378E0 +1329F73D54DC0484177D3C3C06F67397955FF1CA4EF8AD1606B70455255D631A7D6EB92BFDBA14A0 +FF28B2ACE7E81AD666EA9B3A0F5A6BA3B5DFE35044FA4B3D8ED956009C60E98CC132F2E84967F4A9 +8A67B336D5EE7CAF7DD1F74D1FA08619941361FA7312CF225D89CEF97E864C8369EAFAB94D97F056 +5505D825972B754F6729596EEA91210B75DD8F645382ACE36DE60819A02B3B48DD00F5485F9264F9 +FA926D732E2C267B0BE8CA98526F124F97EFDB86132C5EF16B103908172FC51F286FFE45FF253512 +E0033F037FF182BA536A9EB2DF2D1DB257D9C86C46E1B002FB32AC70CA9462E6EB48994752CEBCE3 +9F08ABD4F4B0889283E55500702185A841E328 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndResource +/Times-Roman-iso1252 /Times-Roman ISO1252Encoding psp_definefont +/NimbusMonL-ReguObli-iso1252 /NimbusMonL-ReguObli ISO1252Encoding psp_definefont +/NimbusMonL-Regu-iso1252 /NimbusMonL-Regu ISO1252Encoding psp_definefont +/Times-Italic-iso1252 /Times-Italic ISO1252Encoding psp_definefont +295 321 moveto +0 0 0 setrgbcolor +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<4C61> +show +362 321 moveto +<6469726563746F7279> +show +556 321 moveto +<53414C4F4D45325F524F4F54> +show +962 321 moveto +<657374> +show +1032 321 moveto +<737570706F73E965> +show +1230 321 moveto + +show +1318 321 moveto +<6C61> +show +1369 321 moveto +<6469726563746F7279> +show +1564 321 moveto +<636F6E74656E616E74> +show +1772 321 moveto +<746F7573> +show +1870 321 moveto +<6C6573> +show +1940 321 moveto +<6D6F64756C6573> +show +295 377 moveto +<6465> +show +358 377 moveto +<6C61> +show +411 377 moveto +<706C617465666F726D65> +show +644 377 moveto +<53414C4F4D45> +show +866 377 moveto +<322E> +show +920 377 moveto +<4C6573> +show +1009 377 moveto +<6669636869657273> +show +1175 377 moveto +<2A4D6178456C656D656E74566F6C756D652A> +show +1661 377 moveto +<736F6E74> +show +1761 377 moveto +<64E96AE0> +show +1861 377 moveto +<64616E73> +show +1969 377 moveto +<6C61> +show +2021 377 moveto +<62617365> +show +295 433 moveto +<6D616973206E6520636F6E7469656E6E656E74207269656E206465207369676E696669616E742E> +show +295 551 moveto +/Symbol findfont 50 -50 matrix scale makefont setfont + +show +370 551 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<4D6F64696669636174696F6E> +show +659 551 moveto +<6475> +show +738 551 moveto +<66696368696572> +show +896 551 moveto +1 0 0 setrgbcolor +/NimbusMonL-ReguObli-iso1252 findfont 50 -50 matrix scale makefont setfont +<636F6E6669677572652E696E2E62617365> +show +1434 551 moveto +0 0 0 setrgbcolor +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<706F7572> +show +1553 551 moveto +<72616A6F75746572> +show +1737 551 moveto +<6C61> +show +1801 551 moveto +<76E972696669636174696F6E> +show +2060 551 moveto +<6475> +show +370 611 moveto +<66696368696572> +show +535 611 moveto +<696E636C756465> +show +716 611 moveto +<6E676C69622E68> +show +891 611 moveto +<6574> +show +962 611 moveto +<646573> +show +1063 611 moveto +<64696666E972656E746573> +show +1310 611 moveto +<6C696272616972696573> +show +1522 611 moveto +<4E657467656E2C> +show +1714 611 moveto +<766961> +show +1809 611 moveto +<6C65> +show +1880 611 moveto +<66696368696572> +show +2045 611 moveto +<6D34> +show +370 668 moveto +<636865636B5F4E657467656E2E6D342E> +show +309 769 moveto +/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont +<6563686F2074657374696E67206E657467656E> +show +309 813 moveto +<6563686F202D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D +2D2D2D2D2D2D2D2D2D> +show +309 857 moveto +<6563686F> +show +309 901 moveto +<434845434B5F4E455447454E> +show +309 945 moveto +<6563686F> +show +309 989 moveto +<6563686F202D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D +2D2D2D2D2D2D2D2D2D> +show +295 1106 moveto +/Symbol findfont 50 -50 matrix scale makefont setfont + +show +370 1106 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<4D6F64696669636174696F6E206475206669636869657220> +show +849 1106 moveto +1 0 0 setrgbcolor +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<4D616B6566696C652E696E20> +show +1087 1106 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<20> +show +1099 1106 moveto +0 0 0 setrgbcolor +<706F757220706F75766F6972207574696C69736572206C652064657373696E> +show +370 1166 moveto +<6D6573685F747265655F616C676F5F74657472612E706E672064616E73206C2749484D20646520 +534D4553482028766F6972206C61206D6F64696620E020666169726520737572> +show +370 1222 moveto +<20534D45534847554929206574206C61204272657020666C696768745F736F6C69642E62726570 +206461616E73206C65207465737420534D4553485F666C696768745F736B696E2E70792E> +show +294 1323 moveto +/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont +<5245534F55524345535F46494C4553203D205C> +show +294 1367 moveto +<20202020202E> +show +294 1411 moveto +<20202020202E> +show +294 1455 moveto +<20202020202E> +show +294 1499 moveto +<6D6573685F747265655F616C676F5F74657472612E706E67205C> +show +294 1543 moveto +<666C696768745F736F6C69642E62726570> +show +295 1660 moveto +/Symbol findfont 50 -50 matrix scale makefont setfont + +show +370 1660 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<4C65206669636869657220> +show +578 1660 moveto +1 0 0 setrgbcolor +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<61646D> +show +664 1660 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<2F> +show +677 1660 moveto +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<756E69782F6D616B655F636F6D6D656E63652E696E202020> +show +1207 1660 moveto +0 0 0 setrgbcolor +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<646F697420617573736920EA747265206D6F64696669E920E02063657474652066696E> +show +1862 1660 moveto +<20> +show +1874 1660 moveto +<3A> +show +309 1765 moveto +/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont +<69666571202840574954484E455447454E402C79657329> +show +309 1809 moveto +<202041434C4F43414C5F535243202B3D20636865636B5F6E657467656E2E6D34> +show +309 1853 moveto +<656E646966> +show +295 1971 moveto +/Symbol findfont 50 -50 matrix scale makefont setfont + +show +370 1971 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<4D6F64696669636174696F6E> +show +662 1971 moveto +<6475> +show +744 1971 moveto +<66696368696572> +show +905 1971 moveto +1 0 0 setrgbcolor +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<534D4553485F535243> +show +1178 1971 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<2F> +show +1190 1971 moveto +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<737263> +show +1251 1971 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<2F> +show +1264 1971 moveto +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<4D616B6566696C652E696E> +show +1552 1971 moveto +0 0 0 setrgbcolor +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<706F7572> +show +1675 1971 moveto +<72616A6F75746572> +show +1861 1971 moveto +<6C61> +show +1928 1971 moveto +<6469726563746F7279> +show +370 2031 moveto +<4E455447454E> +show +592 2031 moveto +<6FF9> +show +664 2031 moveto +<6C61> +show +723 2031 moveto +<6C6962726169726965> +show +904 2031 moveto +<64796E616D69717565> +show +1149 2031 moveto +<6C69624E455447454E2E736F> +show +1481 2031 moveto +<7661> +show +1550 2031 moveto + +show +1648 2031 moveto +<636F6E73747275697465> +show +1868 2031 moveto + +show +1912 2031 moveto +<706172746972> +show +2043 2031 moveto +<646573> +show +370 2087 moveto +<6C69627261697269657320737461746963206465204E657467656E2E> +show +294 2188 moveto +/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont +<69666571202840574954484E455447454E402C79657329> +show +294 2232 moveto +<2020534244495253203D204F424A45435420534D445320534D4553484453204472697665722044 +72697665724D45442044726976657244415420447269766572554E56205C> +show +294 2276 moveto +<20202020202020202020204D45464953544F204E455447454E20534D45534820534D4553485F49 +20534D45534846696C7465727353656C656374696F6E20534D455348475549205C> +show +294 2320 moveto +<2020202020202020202020534D4553485F53574947> +show +294 2364 moveto +<656E646966> +show +295 2481 moveto +/Symbol findfont 50 -50 matrix scale makefont setfont + +show +370 2481 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<4D6F64696669636174696F6E> +show +665 2481 moveto +<6475> +show +750 2481 moveto +<66696368696572> +show +915 2481 moveto +1 0 0 setrgbcolor +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<534D4553485F535243> +show +1187 2481 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<2F> +show +1200 2481 moveto +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<737263> +show +1261 2481 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<2F> +show +1274 2481 moveto +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<534D455348> +show +1432 2481 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<2F> +show +1445 2481 moveto +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<4D616B6566696C652E696E> +show +1738 2481 moveto +0 0 0 setrgbcolor +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<706F7572> +show +1864 2481 moveto +<72616A6F75746572> +show +2054 2481 moveto +<6C6573> +show +370 2541 moveto +<6669636869657273> +show +541 2541 moveto +<717569> +show +626 2541 moveto +<7772617070656E74> +show +834 2541 moveto +<6C6573> +show +910 2541 moveto +<617070656C73> +show +1059 2541 moveto +<6175> +show +1128 2541 moveto +<6D61696C6C657572> +show +1315 2541 moveto +<74E974726168E9647269717565> +show +1600 2541 moveto +<6465> +show +1669 2541 moveto +<4E657467656E> +show +1835 2541 moveto +<6574> +show +1893 2541 moveto +<6C6573> +show +1969 2541 moveto +<626F6E6E6573> +show +370 2597 moveto +<6F7074696F6E7320646520636F6D70696C6174696F6E2F6C696E6B6167652E> +show +294 2698 moveto +/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont +<69666571202840574954484E455447454E402C79657329> +show +294 2742 moveto +<20204558504F52545F48454144455253202B3D20534D4553485F4E455447454E5F33442E687878> +show +294 2786 moveto +<20204C49425F535243202B3D20534D4553485F4E455447454E5F33442E637878> +show +294 2830 moveto +<20204E455447454E5F494E434C554445533D404E455447454E5F494E434C5544455340> +show +294 2874 moveto +<2020435050464C414753202B3D2024284E455447454E5F494E434C5544455329> +show +294 2918 moveto +<2020435858464C414753202B3D2024284E455447454E5F494E434C5544455329> +show +294 2962 moveto +<20204C44464C414753202B3D202D6C4E455447454E> +show +294 3006 moveto +<656E646966> +show +295 735 1 264 rectfill +2125 735 1 264 rectfill +295 735 1831 1 rectfill +295 998 1831 1 rectfill +280 1289 1 265 rectfill +2125 1289 1 265 rectfill +280 1289 1846 1 rectfill +280 1553 1846 1 rectfill +295 1732 1 132 rectfill +2125 1732 1 132 rectfill +295 1732 1831 1 rectfill +295 1863 1831 1 rectfill +280 2154 1 220 rectfill +2125 2154 1 220 rectfill +280 2154 1846 1 rectfill +280 2373 1846 1 rectfill +280 2665 1 352 rectfill +2125 2665 1 352 rectfill +280 2665 1846 1 rectfill +280 3016 1846 1 rectfill +showpage +grestore grestore +%%PageTrailer + +%%Page: 2 2 +%%PageBoundingBox: 18 18 577 824 +%%BeginSetup +% +%%EndSetup +%%BeginPageSetup +% +gsave +[0.24 0 0 -0.24 18 824] concat +gsave +%%EndPageSetup +%%BeginResource: font NimbusMonL-Regu +%!PS-AdobeFont-1.0: NimbusMonL-Regu 1.05 +%%CreationDate: Wed Dec 22 1999 +% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development +% (URW)++,Copyright 1999 by (URW)++ Design & Development +% See the file PUBLIC (Aladdin Free Public License) for license conditions. +% As a special exception, permission is granted to include this font +% program in a Postscript or PDF file that consists of a document that +% contains text to be displayed or printed using this font, regardless +% of the conditions or license applying to the document itself. +12 dict begin +/FontInfo 10 dict dup begin +/version (1.05) readonly def +/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def +/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def +/FullName (Nimbus Mono L Regular) readonly def +/FamilyName (Nimbus Mono L) readonly def +/Weight (Regular) readonly def +/ItalicAngle 0.0 def +/isFixedPitch false def +/UnderlinePosition -100 def +/UnderlineThickness 50 def +end readonly def +/FontName /NimbusMonL-Regu def +/PaintType 0 def +/WMode 0 def +/FontBBox {-12 -237 650 811} readonly def +/FontType 1 def +/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def +/Encoding StandardEncoding def +/UniqueID 5020945 def +currentdict end +currentfile eexec +E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89 +699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641 +2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2 +5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF +9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A2261C63C769D2F4B60FA2C438AD7D199D8E4 +5F7E7C9A605C8CA14E21FCD81C9A515FB8DB6F99604534D06EA9D87FE0FAA852899C9D0595C7A97E +6C55F79FAC45CD38E87B10D210CE7501E88C8FCD3444354365FB893A12F596AE2C1E70D5819EE0D0 +87D10BF8DA96F3DABD5405D28C4228C6C31BA4052464859640933FEEFD8071C0C84CDD829A9B1D0B +A01F25A4D50EE2EA2B45160CA6333B2D2800306ED2BEFDFE155E9D9F9342EB8D5B0ADBF2460CCC98 +643FB1287CCD28ABA7B5CAB92EC39EE2E918990372B16F8487EBA30EAE88708B6CF33B6C015D8096 +C7CFE2F139F52052E3925C0D50FD64CE68236D59CB83EF56BFC584150EC38065059F3308AD6F9A99 +F83EF4E6CB13855C8175E31417D190D036B387D3952344A950F4D8C7781B307A094DF1ECAEE4D2C2 +FD747BC6F7F9C6BD0E90C19294F96C8C5CFE88FB34C477574A1B1630B8CC591529E59B20794DA32E +61DECDA8ABBD1AE956CF74012AA01D42EE01E861B0AA6897C864788AE59DEF43C493246FDB1ACA55 +4C12594BC7B33657A9ECC9E3D1472EF826073F632BE540C35FF6FB40566773F3BB2204D3A579A08C +CBC844C14B18C350F003B9DA23A570C362D6003893CA32F86F59B829C78EE3188B6E3F7FA81D7F62 +2825C639638DFB78B7AF1F500F5B450FA54DBFA5CBA277C794ECE93275A3DE0B452FDC8DDC2993BA +A42F28A636008CDCB03EBF71BDCAF35019778993443F88412AD2AD0D7155A3944606463266322DBC +0244B07DA1E9C27A27B59664E8566D7A54CC03E995AAD008B0A17E2C3EF61F720CE7F7788599C4E4 +4C709CD5C31B11107F16AD70B17B9AFE2E8CD922A7428DAC171427FFAF51067307FAB0ADB530E701 +FD22DA22C4CD3064067BD4F6089C4B2C87937DD426E4E9D2F60E608288BAC9056554D04947E69200 +61E379CF5E81BFD32FD37EFAC1F61CEBEE551B0851516471A7472C60DF89DAA9EB1DC5A67E479745 +3E69B9E22BAF4E3CCA4192D603295B018C4AB69D18DE52DFDF15E96B557F290A4B8C5B1E7A6CACA8 +1F2351B97ADFC36995ABA43803A6E5AC04A3C93495F6D38106B8B144449C07D1358210F9176E1565 +72363CFBDE576BFDF99FA329DD1346E83F79E06CF68250CA57A68931BC7F342AD295D0CBA17AA95B +B8EEB53EA6E8E660B814E9F857CECB14F44A43288B69A9E7908D55BF19E844359879D28CAEF1C38A +36420185D20DFB32C2E002202800E8EF3D67C5D50E919657CA958B538D537D503444865331D79BFC +40312068D72364503BD0CC84B5F30A74D8B5B6A26AF2DB764564FB65A6BA8F9051AE2B4EA458D46A +4569F30C6E77DC097356770362E6CF3F1661074778EBB44FF7D1E3B64FF75E77E11FE525BB121C65 +46CFD13300CA1F02D571B82A5825E6226D14FDCF27F06D87452A8B6C5DCA658535CEE2A795E58137 +D48E566B69D53A0C3B766E84C51EAA221C46999CC8065ADB2F129D5B630FAB1814C0C33B5AEA0EFB +B6E994D80941B53079AF96D90A0B924F9B0E319BED9836B8F9053F868363D3CA554CBB181863301F +8CB940872ED5FA7BD18CE39218B5AD8AC57D0F752D941076B1C64D99BE0DB86D7A6D96510D772EB2 +4C587F11779BD21CFE5BDE1F29C1EF9022B2B8BCD7F91153C845906722477829C40111D810480F3C +F62DE8DBA7FD86CD236E656618CAF6FC46827FBC4898EA7672F8C9971AFE43E0E01EC8B77D4AF48C +BF1210E98C1DB15C16D149BFF58AB0270CF015B107A3A50F5DC8F37FFB92EEC8CB6778DDB7CE4AAB +C464C4AFF654223006A550EB52485A23D2B4AA7198D3CD54418102F1E9A4FBDE37B841E56F5C2C53 +966DB9B66B000E4588282E3FB80C2C519339F0002D2F83C979EDC5827A3B3C8EF8810A0F9DACB6B9 +998E9AF6551F56313DC4011904CB979AA2D32B11A811BC248141E4B9734D9FB7982A5671002D8279 +CAB93ABE057474628DEFC95D43890DB1ED34CFA8A20BDC3D874E7679A396158E522ED0AB969A4E3E +C7E4474E192590504D54DEB7B260B7935C4E56548A7D121AC1F741F8CDF259EA1B5813175A77A1D2 +D30BA26F65EB765A04C09ED51F69F41551ADF399E6AA2FC09788137BEA4913F17B8EB838C38FB272 +1FDCB55FD65697FF0B850E7D3D1CE266BF90F7EC06A9A0876BDFE767D3A918B092FC78C775F945CF +1F96E859C03DBF630D9A940939654C3549D8F7921CB94EE23D5A0535DE9DF31EA0F937F860B4F220 +A99ADDFC343D7CF7BFA0B803C12C26403F0DCFFC8EA786D0D8A8D9C367419CA8AE41190CE93A8086 +583A1E6C9D70B612C84D87D2EEAA71EC2DC12F4CDE6A821303D5F6A9BBDB7EEDCD289E80FA3B75F4 +7F481B50719DCF4A142069393593B9AF9CCEEAEC56A35B8787193D7C88113E9E1E221D151E093B01 +9EF89F6118BEC4735103CC8003CC5AD1B6727B3226CD44C497DA7052DD681695DBEC3397F9598C91 +77701C73BF0594CE93F23D50EC5BEE2FB9DA1FC966DF148B27B28EE3C89526DD6625E2887F9FA076 +7C127C609EE315626BC14D274FBEA56528DC06A27B2D476D46E9E7916590B156A5DF04A6CB15E362 +45D77021767B6E5BDFCC679670263FD891446C3371B11BB6E1DF60F960AAB4149D7753E6A5C33810 +C42C8BFF4E935003388506F8278BD7CB672F132E065AE684DCA0B9064D01DD620E7FFDFE04F14277 +EFE8E60159BA0FCA3FE2F28B902D4AC275D19F0AC6971EBE827C4A232D87650D2688345BCA78F879 +077114F0463C5F058107B669566F8171E4E284D278405580F04BFFC9902784216E0C9A17AA9B2935 +E66E18A783F723BE044389B7E9D62AA36818FF2EA406C3C1A9D2F3436F3EE7DB8BE86AFA8DAA6A4B +1B84611350D8D27605509612B515E16AA843164D5D0805E36A2B9EF74C5F6A0B9D59A04B55697123 +27F4B1B30E9587CD103337639967CBDC655AA46E80D2CFD24BEB50815B5338E522B3A7AFE8362AB4 +F05D8BC52BBA9C5089ADA8C89529B0275AF422EB540D31A938B8740860756325B966B36817115213 +FAAF92DE63F6BAE1E0064BFBC5588098B61EB83C71F1C2082436D37DAF1ACBE186FEDC4BE7C1233B +6F18BEC5F99002D21CB7864E4811F7AB3C03003E1E4490AD1AC793BD28FCD5EF0E6CC30EF39A08C5 +2F71939B0CEF620DC69E31E39D6DB969049031B0C92EF2DB653D97F370141456A52985076B268652 +FA2648C792780BAD637C4D7581FB2D62011D57E293719487CF2D1F013CFAA532E1C2D39178D51272 +A6AF041440BCA174B5CC902BD7390C7D3695056CB4BD7791F9FB6D88E7A70DEF2C97869F5DBC5BD8 +23C517C7B7C39D624DF627DC9653EA5347BFDA80B723F05F6DBB4C9EA501D862ACE05B9DBDF21B70 +56FBCD8C6D4B85873DCEE6166C8B5ADC0316CA12D9639F361B15A42F00E1D62EDBCA1111972FA0F4 +5758BECB31DB38316F3CDFE1B41748C93ED58B67E9B57ABBED5924A6D53E99FBC9A994A6489A8BDF +13EB685548B4DC6D62DA7426C22227D4D43B6FFC7B5EA91C896730253E8941AFEE588359C2BECF6F +FC415B9EB6D31CCB0F6C7F85853E6449FA6D627A97A3CE8303F148393ADCCCDFA2FE085C6908BE5C +3C05AF00A6F02840206C3253A559AC5C049BDDFD11AD9B118403B84DA10AE3C470CB9A9A2D1D7B73 +2F59F5FE146DEDA60AE750F551AAC934621B4470E1BC324C436303E25F81D0DC3188BE0D6FEC5414 +C20E4CB18952E12CB6423DF7124627ACDE145500D77A97A8BFD9CB50D1FAA008E2CE2B2505A4749F +1EBBB092C347023714055A9B63353AF9E7FEE05BB54C9843698101F79888A91531773830C2C967B5 +88D3ACD2192883D5CE3962D51084FC653EAE2C5FB2DA41DACEFB5C76812D2EDB5B109677289CD199 +8D457FB1023A19AC67295BBC1A9A20A426B06A368DF3C5DD083CB1180D287F5500F2C635EDE157EE +FCEEC5503447382D15C748C1E35F68753992E5C90F900DE54D18F8E1B355D1076ADFB1F3590135FA +D1A36F028E44F48ABB149B80CA9A54614D467F8D71CB310BBC7AC7100261092DB8C5BFD39E0AC6BC +2C9D6CBC3A8C05FF8A74CB21608EC4A4CFE4CBAA2D056DBA14206106044DECF59F957EF8A9CADE4C +9B19D8D30DD4FDE6A9548E50DB51ACA73330142153FC36B69C1C8D5B26D0C689B7040E81AC2C864F +D7C097C99BE5953843E172C97AB5684F35FB03A725A89DBF371F08DDF40A1531FC1B676DB0E1543A +EC6E97D3D2E4AA3D5831D8B3C952ABBFA112352814FB6FAB61A0D680E6640F6AEC8426200CF61286 +F7422CB2F78C61EBAA36D47EC16D7FAF8B4AF31D090CDFA255D9D7C61D46CFB22A7D6E1758E71ED5 +67E00CBD8E8F468DDFB477F091A2F915627F22FF47B876544BC1F03B6BBB98385F009C20BB1AA2A7 +A78674692B8EAC2E3C8069B79E679338DA57F72976810F845BEB6B9ADD32B95D78E5E60F16DD1668 +9C05FD82D36A3115BE8ED494A74DD211D58A2CDF983FCB9CDC29BF7F0E29988FA23560EDF514BC1D +183F3B2A22C09FB179B47E05ADEF48DF02F31C29875D1915037B19407764A4292FE44E741651A8E3 +BEB5F0D972B6327090F664417C84F84FFBF0AFFF8B1D85C822D90730AB4140C42A51AA8B1DBE4398 +4EA8566040EB8B341CCE23FD3F69DD235A080BA5C69AECB9BC732BC2D7D40617DDA6B79FB6EE40C3 +556C7DF9B23DAD89E94054B1345DB8402AE679FC4655A4A776C0150463F8DB2BFC0608EA1F124E22 +1DDAE6026B5E5D007A7E4A0D6B3B0CF3A2669E67C5E4F01551966A7BC48F2F4B6A87E740D8095E63 +F77C7A027F26B52F2299DE5B8A2F6209BCF3D31CB0235F998F781E5CC81E31DC424E008D46EC0920 +2951E5684804A0592EA47D6C788A20487BEA2EC8F2E6C1D7F378B62DB43CA43C4B366F8B4319631C +FE9854F0E10321CFA3B01C873584863BBEFC23C72C05E695B56E8A52E89AA2DAB543834D34DCAC5F +ED08DC51825C5257AE59850D101D84F4CAA1D29FC932F9E0EFFBF7A9A7F3685F61F0490CD3CC8988 +2DB52A757A6AF4C4E67B407BD2316B1C0FFE7DC54E43C87B874F57E4903334E2140B011484863CDC +ACA331175F2CF3D72E0042855983AAF8853D3015E870FF0807014C31D55060DF3FE1FCE157324481 +2744AB51322444632F9AFDA6706E320FFE82B8CBE242A19DF00CE73EE48E25FF49D5871BD3E60652 +298FE3E8D400609E232E0DDC794C0579ACEF89E841B2EDCA50D51151F65E8C1CC3B01EF1870558F0 +BF5743718C3E068617E81BFE120C6CA16E0924BFC2541177D53671CAA3AB641C41557DCDAE1A3461 +47B5E999C4541B08B4AFCBC187AFD653D5B5F8386DF6AD8FE69E21BD0567DF494F736C6A184FA4DE +48DC9F347787CA96E2E00A296C2DA05C2AD9BC423E9CA428D7F1FA12DC9353A302FB8C529AF8688C +BB543B45B2717EBF8F6C497935F4F3BFFD285E0402AB7544B3CA4643AE5A8B5250ED987A95FC1F27 +5B9707ACD0641BD0EE2AE9758494F8D8A51DCE408A38AC20EAF0852D72D84D0C6BE973326793AEB9 +55EAC6FE0A2813A355DCD22F6F2CE56588D1C055CDDFA98878BCEB6A018DB22922D2B600A20F8184 +2E665DF41013CA0947C4237C2BD60A75E2FD1A3FB8C8FA19485730B87461AD466ACB02DF8CA24091 +4FB090B3D2B41EB6B8FF05E1A59D9FD668AF70BA5BB72778953BA55FC5F9F626043450E1D09BC83D +8605098ABEF884639A37809A32565CBEFB3FF39EE53D6C18C58C272BB928E4410E361E59A50F242D +69747A032617C52DEBBF62364AB5A96EFAF642D9D82BA679B1D70FAC10A4EB62FA5CFC308E86368A +AAD7E75948F43598CD1C544A0D4091374D7E88D4522CBE902391641327E888E7748FA889DCE67ADE +61699E7D77763681CAEE9B1CA8837B2F7EF9C18CBCC538C465C8E2DD34616953CCB6030A222C728B +834911C1A179E2C770289407AB28B303E724D97F747D6134B425216A64C6E0B60F633E2B85300047 +E4C90339CE030A0FAE31E830C8ABA5AB3386A3B69267351A7BFDD66356AE5E57FB2994452993E90D +E7C4E260ABAB93C37831856A650D56E44172FECA01D6C7C380F250B82473960D2A2A5FB6B4DA668F +46E624ACF7FA0FD4490F485D640A3ADFC9F8652E7A38CE5799F770C3606DB4B8B947F93967F779E3 +A3C0572F13A5A187D31D7BD12A5C7BE23CB6ED6192086241B76C5BA6983DB9C93E4B208D707D3760 +F03CD6272EF3A4CE89B8E52E6AC5871A3D03EB975759AB4BE239E5EC7842CBB333E692CC607C722E +185D3C39164DD320C6945629C70FF66A5237C0A9520A1FAD6EB9816069351AB0F135D90CC0982B14 +7D2294AE4A38A527EE40BE9CDE2512AAEBB590E134388BB171D0956A7C4566D65A9A041BE6C4F883 +6B3EC3D2ED1B48B566A783292B15B6127920D247D494F070BB20BEFF60640B11B276DDEEE49706E8 +B2B21BB40B7F00AAFC594C492C25DCA774E0B80D82E927448DE2E74A9D0DC7AC9260096EAF187B6C +D6AEAA6D1DC4205B4411122751A5B22688404EA7C5861730371FFAC10F5AFD4727A0E402AB5EA757 +606B75EB86A05E8F774D6E430A1A3FE2A37EBB06700474239FB1CFA05EE44B91B82244C575B52E7F +AF934B04EEB0D933FEB57EBE326D75821C8B23EAA85B583AED4320B7F04B9F2DC591091216FDE52E +064BAAA9C2C9D9714B95A4558C21F3CEBE624B5403B31508F178581AF6863083ED762F1E2E34A45C +FDD71660D626FF8648F5D6C5E580D4765A67FB6159EC8077A9F0A88038C8D3D7C77FF0926E2123BE +874F7BCAF129D55A5B5960F824BD1728ABCFCC51D23936DE9A25C408D786E44C3A2BAFA4423177AD +060D21D38E15E23EB6FFC0B4120E814695D423EEFC2744A1FC81B4DF89D76F0A6803D8B14E75538C +AAD03A72517B86514F6952F6FD619D9E910D980F00964DB325318C045BDF79647F453D4A5CF4E61D +D5359782827229310405FBCF6107C3AD9DDEF9A9A339D5D5A6EB2E7838A0A43221BD62CBDF732DB0 +A638A52016FB35BA7761AEC846A023D3BF2D1BB183543E81EB7CAC1E5970CDC6F068C5EA118C7AAE +528D1396E6DC939112DA4460C890EAD5C01BDC438F5BB734218BA6270ADD0DC1778FD8AB16831D6A +302B814A1A44B07EDC65956C9E6CF4875DF521F3CE5B422F71081B6D69BD270F739095C9E81C0377 +934A8BC6390C420C4E4CDD9CF7E32544C68D884E15ACA3BCC07FC8C132D8FB9D752C15D75C52C288 +57E2EA461A6FCAD90C56843513F74461F18D7164BC597A28AE4BA7C86EE1703535A9B9ED50122627 +71FC12F102E800E0E1AF7BB46681BD2B14B614CEA91B7B2AAA35235DE76C0E113C92688F8EC81277 +D58C3406778E1EC1CC15F1CD9A137C8FFDAAB99ACE3BFC782916F1A877170589A92DC921E6740A22 +B84DC6BACDABCC76E64C79E3A588D80F8F4D376E1B426F15751CF7391102102F0AFAFD8B22DFDEB5 +48AEB5F30B1673023D22054A13391A0EC08DE6E7B685A0D031AABF20B7C62187C0284892D5EAADF1 +21BA28263EB863D5E36EA9C06A77CCFC0E17F593961591F84D82AF823EFE41044C8D606FEF83CCC7 +B0E961E7994DF8A3CC36B209D953E250ADAB8D22D7F2B4E2C9CA39EFA2D93E56195C1560E30A5190 +CC5B17FAEFCF250DF79F6B624A4B917E11C332222FCCFEC4F6A47BD9E75DA9854FC3F7AE554E91ED +DE144D7AEF38A0E3EDB5E5A5626374DB94F022C8CF549093041DE00D7269B7CE544E748439BA2870 +718C08E58FB4A77D93EBC04B7957D272AE1601D41BF85A2BADAA0DF73B0D3841D4839C85677FB2E1 +5F1D6CE592669FF4BBC9C69DBA334DC37706F2F6BE83D5863E8CD6A30C08640AAC4C233684E66B4F +E6B62D4A8BE9D531E47BEF5640D9B5C27D990092BE1597F6995C8A77BE9C18AAE6C1CF130775DDAC +41D34438FC7AD8E042CB56CBF2944932EBA7D053E9376FF398367450E35A1945FE23E05C921096A1 +5454721FFD0F429A3E06DC3ED36F1C170BE79C66996EF8337AFF85B90C5D3A4A94455AE9FA32E211 +7A63E59001F052D5F6223125BFAFA40901E98960ADF7BB886729DCA82FC3B8CC52B37FF2517299E1 +D769057F8154FB95582F02CB0BECC873A9C71796ADBD3E91324FAA94F2C41CF57C30B5897D031C02 +D256C909E080E70BFD1F32E69EF67031138C2DDCD1A8E4B65E485C23C3E450ABDD9815512D6F34A8 +4B9DB715DB2C7A93BFB424316E1AA44397749CB01088428F149A3B4324737ED9957FD388248462AC +1B2610D72BF5C073ECA567E7385CC959E37CAC7E05470160FFA5A9F63B8E9B082937E911586EA165 +374938F492EDF28CE6020953A5B5CCEC7737F9D9CC8538C4339567AAED3794ABA3B9F4EAE65466E8 +E326F6C399B36355935FBDCB9972F10B13494DC25097FCEC5A6398F275C8C151558E74C5175F7BAF +4155E36B733F75CF9D5C5979B0764F14D8306E06BA24BF791141E404C69F3F8FCCD91B9C58C2C671 +AAE7D4F9E5D6414E46ED633A5F78AA5BF04E652246A066EAD9E582B181CC196EA2D3CFAA383B5D0E +4CAC9336E119C08CC6AC55CBFBAE147C623B400453BBF447E96DE036FC025624384359EED7C7D5F7 +858DC0521377CF647A157FC3F188DE5EEF094DBA125510FDE34C570D7BE76AB5DF0A28BF45DDAADB +EA7EEEDB936332DFE93081E0AFD3FDD46BED08D6914B2EFCFDC41662A33B90B03D76D34F48D30FC6 +BBBB600E90E6AC7243FDF026762A44B4D6E4ECBEF48C9D7B696AF29EEE063E557D8FCF0F09E0136F +45D17E608DA36E59F2AECF8493F8D62536119B5F7E1554DFE3F6E8D7C9A2C6F557D18B4AF92C9F6E +050975C3B5C54F9B5F4E39D600B6FA2CD6DE203A174028CBB2A201AF126D1013C229BB82CFD013ED +199D01E51EE2780FE896E01C63C655087A3E61A7F1029FA5E97EA1872F1B45F22282DDC317E17926 +7368CB52DA9444F6055A3C653659CAD2A1D8712BC2B1B32C1DC6906D957FB88524EE066156ED6BDE +B8D832F9338F9912E29A250A8C4674E667C1C278B677AEC9972BE83CBA3FB779893FCB8F81A323AC +91474BA2A2334A07BB5628E905C518E634F6761A3289056F83D5DD7B3890987EEE1C18FB2D379CC1 +905F1AEB3B3D2AD578F0D6C845D2D40C4BCEE3F71C90E68E5417BB8CDDD878D83BA80AD8485F4067 +E5C3CABF28AB56CBB219C0AAB8FFC6C7E192BEC8CBCA1459AE4450AFCC81B9548F40CE2622E5A7C2 +81F74DCC02DAD57EFD92D072318DDF05BF42F1EA8163071E23949B0179CF7DE64677CA99B23CB926 +B3E294194EC13397EA1DC9A5E1CDCD828156CD71F81B64167D4FB01E6002713BD8AC6F82B20CD369 +9C6CA4704DC5C65A2D66EB155B7AF1C9BB46469416FB49C1C7E17A30A5F045271D7DF3FFF2F42C6B +470701C381E3456A500C6BB3D0E47B4D91C5F34B49BB6272F1F8698B307D89EDA3A1565DAD1C0864 +627560CF922DCF5B34C67860352390B282F95394AA2CDE0E97CE3ED39546A6AF1C52BFCF81A29BE8 +2C47C99E8050E4889E4575B75F39E662F2DB7420673797E2ED3D67CDA7AE2C15D0A0A794D57D168E +BE13214E89E0209AB2C0EB7784E9491AEFA3C02D0DF3AE5365A0FC4AE023CAB528162C7A1B173664 +9DFADDACA8DA5FA18B7D6489E4229E9E24D38A620464A744A5C60F6F9D334B908706B738AED18669 +8A8B278341FA4D65A0A88680BA484694921512F7DE93337FC1C02BBE6E64AF2DAD07603279D87329 +1D1F4D39C1DD6D89C90F65240F4808F6F1115CA55B88E242565E59F3BBF1F10EC7B88872E9AE61D4 +4CAE185463EDFAF7DF63DE4D2207D307AFB61501892965170D2945846FCF5973A1D458607F50C15E +06E5BEC715E0C156259AAA6C735593E5564F65F443B78CC7512EC35A56F126DF9D30974A40872E42 +65E1AE5FD483CFCBBBA26DEE426CDC4721F19C3FDA86ED7AD4FA1120F63669BEFE7002B128CEAFD8 +C63E8AC09943B6CBDFB3D2476A026C00A8FF81B1F651B97F310C82ABA5F388CC1DB5AFCFF5996D52 +52A6A42FA4D972E41EE56088F78CB966F9051171C472C774879AECFFF08BFD9CEA40D7C298922ACE +64F28C14E0B81F4DCADE81D71DE3983D87D905192EF13CEE71B2D3FF1A88AEC671EC318917DF98A3 +C9054E372D22A3CEC82FCC217F47319A40900312F6E32B536B9E7A7FA0837EC65CCDB5FB0D414371 +17596CB39D9382262DE6E65379D3A9709B2CFBABF5FC5D5B352425F06F88CD31012A2A4147B112F0 +C1C0ACCC808CD625E0228EEF66661F70AF96D3DCFECD402700E4F6522AC9A856DA466D55C84F65BE +2810A1565163872D62EB81333A698ED7B68352CACCA2D7AD38AB55C19E4F5582F75818302F5FDADF +1DCED09D94872F2D48FB636C8E38C7563C72C771A08C6B1F041F3532BDB39006C89A33C09BE1E3E6 +03622D891F98010BF1DE5355F557A1E09448D486ADEF565705277B31B8BF2B86761E32631E3435B6 +88B79D566F1747BA456DDB43CD239FB47FF7B425EAA4C657C8EEC26EE01AED07CF916E77D53634C1 +37AEEA009C6B515B6342C54BE2C7B95955B1A9DA277A0ABCDA2346E88018C726F481F71D6011AA42 +F8852F2E5749518FE3B3AB668213FE1A05C10A1C53953D75312631D6BBBA01D418199DFEFF8CF548 +6109B099FE8E2F606165FE30F532C03567785D5362AA873C9D3EECEB20F1945D55F49B0CCAC84967 +59FCC7292E46938943C262D78F3212D3F9D0F7B103157F423D71B1ED54B2A603F4C269029918F238 +EC6828FFCEC66009DB9C9E59534EABB183F31D7AD4C57B1BDF0BD2CE5A421882BC10CC1BCE6A970E +2B586BB221567CCA483989DD0B8DEC424C1D1FF042DCB7834423CF244EDA28D2D969B17440CAEAF0 +24A6119DB010CE366821AFA424D1B8299609C04148275AE6E5257A7ACB3C766C747CE99CBA2D703C +F19B7CF301B634D8B613DDC4AFE4633A4D77BFF8E00CFB5E289EBBCAC90A24307E7941EC1685CBAE +400CADD876FCEF7F6557EEE167D2035A05120293527700DC510B038A496BE1D5CBAEF24ED39F7421 +1A93AADF22214ED606A80582485AFE358E3A46D0671148998A3B3BE209467009B43400870359D418 +9A8CEB4D5866AB52D16D9CEB1EAB71C07E6CAA34B70E3096BF7604C22C40D5FBFEEA616DA3BABD59 +DCDB97D883FC8742B8267A16A99B7953225F7144568D566E64542C92E538AC140C851E5D295528EB +7CBB49909B1CAF6409C9BCCEB325468FA0B5F7CB2987382616B477CCFE4F4AC79E4A6F7165363543 +F04DE5B6F6E1C2E910CDC3CDD6C4C92737198F892337DCB6647BD226C820AC99C65D8E7772BBB74F +E65DCAA8A22C33BC168BF48E40A82700A3A7668C5A9A71E397ACDFEE7D556C5C19467B7AA69C260B +727407AC837BDB7D67DEC055C1F45D8BAC61048C45BC9FB3CEFE7549EAA2992D2EDC126FF7A05EAE +58613332A2BC1465B2BC0429162B907D65F793D236EDDD8D35405866D71B25F62DC4A7E06D4DEE82 +840ACCAABC0774F8A63E9C0F7FC980B3583E7A8B01C46590E3BC04EBA565C2EA94F057D964A78A90 +EA9F52ABFD70F84E44E434BD10A42E98C794065724341F907E35D3CB257161E01C7084E3A0166D15 +CED65DA7BA87DBB2EA33D39BD99AFB93D3548358D08330E807F8552CECF63C84F805205491BA3A1A +622E70C232FADF3BF2DCFD6F0539158D3306506F150B0518371912A25EB96163D73E9EEED42EDC84 +D688BC7F7708D9DCA348FAB4DF62E5809BD094842D0A31DBB7C4B41F94D946810C5EC10B69AABC2C +91A59500B2E5D37F4755DDFB7AE4ABF757F4C5BCF77C7F95E6A616646456FE8F18407080BCABBFA5 +7704287AD26222DF91AB2613951E2D679472F8ADF06EA2A20205EC19972299A78BAC52114334470C +5F5890C2F846B4C6042D73945127F2E3910ECA1C4CD7A16EFE4B4BE38A15AAA710682C3836A8CA83 +FD384970139D8B46FB0AEBB002DD224199672FFA02250FBCFA4E649E335428FC71F50F45E498419E +DB0E970F46894A48F65580881C9C4250FCEF65C9B28699408E18B26FE6DB7F1CBDB767564E73CB59 +54C6D639CE33220C894F36E70F71C9F9AA3FE2AE0AA0E3F2E304EC5ABC661675CDE2E70519E4220A +E26FBACBD01D5169EB844750753E6CED53E3678FDCD08AB93E10067E9C64F38B40B76D99B6CD92BD +F4155A1EA5CC824998B59AAD06E09E5F15EBB2288D66EA71B296616734FEF2796F07FF0D8B047074 +A1111D68B99C2B70FC56E74A51B062F4998ACC85B1943C9477E436E5CD7AB18DBC898D21BB93475A +623BDDA71D7B895BA2D4C10F4B90BF335126F4FD57D73AFA50170F6B3C364922E551D40E35DA75FA +891762FA23401D39260F2E92C7807C746F13BB35CEF9DBF2E76E66A72FEFF095DA482A4DE8A42091 +7065736CF4DE904FB52E649A32255E2030A7B31B686353492F31C064A3C4B0448C4BFD44B8E15384 +FD809B8761EE26A7DFA1758D57CE4F0BC376EB2B3833534B15A83436BA553955ACB5A7A66796AC5B +92DB5388BC53EFA27508B08E82821E5CF669BCE52BB860780F749B4F38ACDF5FF12726BF3EC2743F +01014CDE96FE6B4C40A034E9EAFCA2A35CCC776C2669E6AD138070A40F48ED79136D7FF57E993E09 +B81C543FBADD350FF5B5F7A46F060F88E30FE2D8233832D18B6C323EE017EBC1DF5C838321CDC8A8 +4CABCAB20B60A1A3AA028F36EA6E87C850AF8AF7CD50AA6359038BFA8818821D02CEE8F51DAB8C05 +F7AE9797814D97F3DB8CCDDE45B21DBB15CEE292FAA534A5F317B357F4091F3DA357325B8B9F5EDB +45865415973C143E5E5BAA483FBF2D06CDD4246675EC58B84C6AE65CA743117FF00F229243772561 +31A7F2BA26A9115AFD96C18216CFDF41B7220ED0CB3FCC26C36380007B382A02AEAE428887DC8BE5 +FDD630AC57EE3DC156C7B8B29E687F24442E35CE10BA4087295A641F7139C831F7CCDA6CCEB5DAFE +537CC1A97C5A337D3C48A6AE947F58A30DC08CC7B58DBBB4737AD52783C573FC1E9408F55495A80E +7FDA61F0B9C4F090158F1A416249EBBA936C27BEFDEF19D1BFB839EB70576A010706D8B95657B218 +9C2AE04C11EF9E57FE09880273761FB4302C388BD608FA0C7F00F033C9C00F4E3D5CE2D903E0DA52 +E69C7745EE9FA75E2AD93DC6CB5CCFCD3782A699B807AFC36AD1F62B05856D5DFD6F88831B90EB3D +CD523582A49732E3FD7253126D39E8AFB8458B5F7AD7F94A8DAC13365F433C857AF4A42C0A08C4DB +9887C4957259ED22D13CFDF5995DA957EA5A0F620B0214FBFE08AB6D552DBF048D62CEF6EFF12F15 +3511ECA7833E0E3E95F85E6AC0F95438AC4C126E1F1ECF336ED31CCA7EB216D279877123FD9FCD8F +B5E52B587CFFC4428456DDCA816819A8A4A211D8F1629E5D42BA4C5C356E580C8A22C61D987552FA +A97893816DA73D423686E4EBD44375C257F031318865A20F22115E72BF1EB9F93AAA169C140A33A0 +6C35BD4526A38BE79CF40AD1EFA10411E8F3300A8A8B97AB140EE6734E1BEE6C8EE443D698D34159 +97649C6F10F20ACD80236422E215E146D744A262DA3FC88DC0D86FF66512F49D3F957D3C5CFFEB42 +4823509F33F155057A4C6F37B52F4667767BA94F6B8B62856B553F307E5D230C44CBFDC9A97A45B1 +39FFB2F2565EB0E22026972FAD0FB7B9576FB6F368B61979943A398773600E7EE1DFEFBF26D45D40 +BDA66EBB96A56EE9CAE0B2420C5DD83E24DBA9FF885BB844BF3D2BF93B07325DFF60C0CB5FDCCA0A +C8FB5A2E119D5AF26E53AB8E3B428481C2871DDA26EF0B621CD8572B3C664BC7AAC01A1D05B98F79 +1A7080D294BE81099BDA7982432F3DFF4775C44D23F4F1B2E0162B61A8B2CB5EE8564BF98E2ED403 +2219085FE6194C19DAC98A421826CAED7F1AB1477AB327506010217283894235D7DBFC1153D5ECC4 +8AA7293F19592B4D7E95FE55151889BCD1D7FA7DC2370D2DFE11D7E4EA34B5C7A8E73BD3A348FD38 +9EF45B6167FB90BA44C23E912F9A4F2FC0427ED070592F7110183BFDB2C400393BA7569058227926 +351F07FED4F33633BA03A72AA2DC6B598E49B96021DD868DAD0F352E5722FB714F667C15C68D49C0 +3D822D82677EDFE86FE9668E537DA284068C9B0AED83074C92A5B939296D505B837E6A9DDAB1AEAB +7455A08A114C2222B339284674B74BF4CA9EE0C020BF2A148B439C71C6BE51A94CB64FBE4A7EB295 +5A455047CF5CB348B062ED4F6471CBC3E9ADD9BE9B96879AC7BC71BCE02FD02F17C6063985A5E898 +3D205AA1489DA13C408990ABA1C54F2F501AA172F530480D789C848118C0A74EF98D5F607A067BAF +F6030D887AC6A6497F9A0B38F9705F328AAD4BFBB634F739386177B07F22D5771282444E5EE17335 +B4D0EC86117C697E79A5F4F65FDC08E4904DAEDAB20067EAE2448FD4301849E456D085F392DD1316 +7ADF75CCFDB723E2904A9C0C976D6B84DDEF9D92B0E15FB246C3ECC2D0BF314CFB957757B3A3E8E5 +801F520644E4601D291DA0F7507C06F3B9BB36FC1C70EAA444E14E56C0CFF06C7F853DF36DA9D8B6 +AF2544B853DFFF535A7E5C6FC145250CDDA229956019659D0D253A19A7B51A4E538BDC01F74D7704 +9949C2C97C7EC6392C2E61CCC0992B66DAF1AB08551063E53180D2A67DE496716CCBAA45462D9F91 +B66A22545962DDAB120511FF08627131B95E5DEEB8B4DD9643E7B2AF65C0FDCE11F5F1E8DD468DA1 +8D41C8C4F00EA73836F4F70EC50FC3EC6D358C0658A4261C6D15A582A2C7C994E7882E661855B352 +014576858A265FFBC425160669CE159D07EDAC04D060B44E5800A7AAE8E339C29B929AA81D2F515C +46229D2080D5917AB20AB6B34FDCA8E4AF64ED660A3173786FB1A1D005D575C2A5187D3F7CFDC94C +CC44A38C5CD523E9DA726D8EFA6DA7B6131DFF3435FEE838B2C7D6B97934295F06202D307FF78D90 +6699CB9C5BBB10D1D4DEA5FDA5BFB094E704607083B646D37F5DA1FC7AD21B813F44D8C1AFEAB666 +55AAA19703BEA2E77DF3BF350E17C74B3447A452235919452B5175570A006C7680AC05E8950A62E1 +1D7E3ACA35A397D1E19630D094A86807593C97F4C484E4E06BCFF708B6DCA972E3A0009E1CAC0EA4 +141530F5C1B8AEF5E1B933F37FDDBC4BE22B74FE346D1A3F5FEC0818F8E61765568A2AC04713E828 +F98C449D9A1CCE52D10D61DD8BFD084C8D099A75D89DEA64D5A7CC68BD5B0593D97953DADA976383 +F5015915618AEC56D71D1DCD55B89736395C609B315A3F1E1255432FDBD37F38CC43C354FB4B7C44 +F1A7318B0B7E99C3C08C33B953727B6A6328051783A0A33E3CD9E498346A3CA6A77B517096EDD52A +E443B87643A646C3A7BB97F742888D33F9B3127E61942F4103C1DBDCD8EAC8F9E259773066736CA6 +53CE57E8822651261D847C131321BB9D6626A1AC50D047C0BA47B411DF2A995545BD68EC0287CC9B +31D5DDCA8755EBEB10ACCB3903AB0FD5788E984220443B8459E7C078DA4289F1350905881AD6DFDE +C47302B0ACB0D4AF8CAED02B4B70DF3CF8FEC118F0FC2D3DDE3E494CD160E676E300BC464BD4400D +B50EE43B314E0517037BF971ACD7CD327CB2134893B8A0410E68DDC518F5DEC966C7884CF5FDFE74 +723177F20DEDC039D879056CAAB4BF045062D3904F615C5CFE109AC7A35599C94024B41019B9AFD4 +04A80ACAA4837929F5C9317680A13D157A03B59A5588DF79D2E113F5F51021D6F6F90E8BBBA2C252 +FD10651BE80BAFD59C53A3367BA3C28DB6EB9DABF1EA99F47B503F627E15DCF3FD645FC52C5D5D0F +2F07DB4C25C0D1E1C00146E1C4D973E613CCDBD3F9450CC0F5343D79F05E9492E86A1BB889ADF405 +03BD7F3E7543436859184A5B20BD8A172F350D846B7570803990ADAA48D4B9155A2B4C4BFBEF1E1A +065C08E03928559735BDD442FF1E83E1FA20A5DA57D8BDB2FF5427C034CF0128AF111E6E73099E04 +6E0C240E80A73D7BE72B87834E45898D475521CA3306707631F5C6136199F354632D1A085F12A1C7 +C473868B62E534D15F5484323E63D0574196A19EF175214EB35A90873EFCFB92D6CF68761D45E37E +AA61E1A1979A82009507CA193E44B36A806486665CEDBCF387053ACEAB979BD35D30978FC7659ABB +E844F4ECAB3303318ECE80777A5FA5A9DD91B3D06804C4B4E9B4EFCF07EB89866D0DD8CA390CFD15 +98651417114D78776B1A1D36B4BA17746D6BE7FC123D473EF1EFED1C3BC1D555F914536869FD5B0C +35F9C83F65B0E6BF7A627B9202D787D72C600DDB6BCCE613D88492E13CA0AAAB196E8A49928C62CE +A4FFE2D0208EDA334ACF47F20BD793124D2C5546C03F4A364369A76A0425262F9D9118AF54E37D32 +E33AB25DD533A49DF5FBF1BAF4CEAC2D9D378CDCD13B00FDA432D9042F623DA41AFB80699B5538A2 +5403B0B3EABEC9E8EFCF42FEF3EA9F91766902CD206B0787C187D5370B60AD6DCD002DE2DE8DCDC0 +B4719A797C5E26BAA67665016DA0D967FA1346F9588AEDA174CA001B31213617FE19EA218EC23597 +79D979E2663166489C06993230B0D07973A117C4E3F4A4C93CF8428248DD5389414D679C69644142 +67C7FEA17E35B0CEE456667A9B1875C81B2302BDDEA2818D6019FC1622A82051F60584ABC904CD91 +8676305DC03FFBCC64FDDAC8D8AA9CE2EA00D6C97BC63C8A617DEDFC0E40775649438E9F61AFD179 +5E3B20560B01BE5E0983F136CF48AB206954E41DEE0D9DDD953DFD01CAEB569151D6BC0DFEF29D70 +FAE3E198E7EDD8922C0E0BCB8BCCF1C016142C1A8B337AFA7A05A9D7534B184BF3BF827F371E9BD1 +9A71244ECA1BA73D484CD2FAD54DB2F0EEFBD54B536EBCB5094E6BC2F5B2AAE41F05B4B311115876 +ED42C34F8E643B53372E3F6350DB8A38445822EA9A33E27FB0CC42CEDCD1FE2FDF723FC47C996EE3 +56C402112F24D0AF899B2D00BEA1CFD427998BD22B2A09046D6737814448ACFB10D387547D7009FB +384AF0562C85694C071584236D0F1F3D3FCD0CFB38B77C81889061E668BA7AB37AA60F58A3967DE2 +6F939B79CBF10A9DCC42852561D8D6754F1B660D216AAB1E133FBAA321C56E2584BE5C9BAE20CCF0 +0E8DBE6D9C2FCEBEBAD945C3C04101D2387351F132628786F6D9D4CAB83419288D31F9BC600D9664 +12E6AA457CE6CAD26A4C0671097B98C2384C81DD8B9A3222D4F4BBDA7017895C3EDC26662779AEE7 +40D9D7E24185FB821970B0A3A94041A69E4805EC88EE1EE521981536F2844FB8F5EF645F67D42CE5 +148E2DDE43AD5AEF200EDB3A2C7866C98458A92666E5F9E070178BCC39F65A893102A10564AF4E8C +AAA5075D2F8CD7FAB0401C03AF299EA3515CC93066744EB5AF7CF0ED06675BF049A6E3C211A89E16 +DE5BF0445A7CCA6EE8EB0347454950485D884606651E5887FE8B24323E2AA16DE22FC1FC8C4F06A8 +2A1FDE5758976024068197E1F4506E4D3D8A16D40461A4586338B374A592DC60334402F76388AD6A +457DC3F54E6169CF7AE3959676E966A45609621055EC3AF80E182633300A4418E34A66DDFA6B569E +5A13C9115B5FD3EC1CEBE50FBA247F60803AA83976F00117536342DC3D9890C49B2AC701D370E43A +955118967827760F7091469C5406F08F18D7E3548148CF0E312B1DC71DF67A5E7A1656CF2F47F3AF +F3DD50FFC2FCDAB7177285B29C17CA43019F62AC6FBA52D1493ED7C427526470ACC8389BAE827759 +4958908F517B2863B83292EB5AB3F57FFFB08393CA610FB1FE905D88A0A16AC395E2A2A6DD033D6A +0D68992F830B2E1B95FE357BF672716E88FFB92FFC3D62945D1EAD22BC68C51EE0E10A43011DB94C +44685A5C4576F6EF44CBFB45F2A4BF110A01657DB51FD499767E78058199B31DFD60813F1A344F86 +289F9378231D5B151C92385E3650B4FEB1DC91018EAB8474CBF69FDC1496A4D078D2C351C8196451 +247A9DCF8117E5B637371D8E22E248C64D999015C3FD2311E9950B8EE0922FBDD3D7BFF766BFE9E7 +CE0BE12F318FF2A7B5A9C6D00A54401609304ED2C55F5C1EAC3D4B38355BBD85D66D61636FA6E30C +2E82829376BEC979A6FEEE040E452359768ECF90CC539A546F17AE906C76F14F86FF697797322B05 +1EB311A759FE260C1EEE5DACF383816AAF1294CFFA7BF87A4D9BC595EE8F2C2F86FEEE11AD959D86 +F22FDAF4CEC098942A57E57813A0FA99239E994FFF353C1E781D666B8928CFC648FCF0869FC68468 +BDBDA7D280DFAB8B0B3A4CA35B074B686DE8D372C61FB32305169A1A9912F6541DA16CD6316A6EA4 +51524757BE5CF6E820011BE3859FB8B8578C100FF029680E05F0E0BF11D33FE19460C85EA5E4C0EF +28E29407C8AE6BE01CFA0D5022BF9FB01416FFF722A784DFC8FCE330EC95737A854471D334FDC58F +AB42867A7B62836A8B56466E9A6C1247D46EBAFFB905CD4321970F59FB8D6FF65FDDD34BF913AD32 +2E68455C5FF2D23C1A5EAE687F259BC982B6A384D35440F7C693CF50B9ECAC0B5578CAEE87588B56 +2EB6B7F42034C9F2E545EC866316552354EB3728C7D26527ED75174EAF635E048B08DC5D23E88981 +070AD5641A652F2344956E9CF4C16E652A99F4A644D1787D6D36537489DA4D74E61B2FC4DFDF1D1D +9D58F9C26C5EB63200526AFD168AC57D5611ADE4D4A382FC28BB60F9E7D626A6C67AFBCCD1183C5E +3CF2EF210D0BF5CFA7BB10FA3887BDD4CD96EEEAA8F9219AA2F10ABC0A960C3B57C0EC0313AE10CC +FF1F522124CFC8D2D49BFBB0C193EAFFC5B48FB3FF30B21CB76F0A4C0F1377C9223145BB0468A5D7 +1B9BC25873EA12E1C60334571C67385C00D0B570D3FFC6C7FF0DE62C183C76AEEB12DFFEE1459E0F +C818C621B8D12FA1357E2B55D48935D70BF140B4CFFE8813DEFD479350B20DC2EB1D3CBB1A2D3DC6 +EE975D58C89D61FC50E6A0197DA9A586B72255023DE47DABEFB11E8AA02414C2FF6258A281219B9D +DDFE41BA7D7977D0D6F18224FE22F7D4E9355FDB35BF7ED3418F4F68D093AC48F7D8FE4194FEB6C8 +0B9DC1F74E023C604DEA27089F98C3973FF9F4AD7BF7BAE601DB89B08D5D8139B95EDCF6C885FFA8 +B3E4B0477E7040225733826BACFD1EC4A0DD72DC41734856AB9FB700DF83CA2CE812913BD142D84C +5C83C0B2583768198AF9E885F2BA74877A414233207234AA5F18840557CA11682AABDE8993533887 +7C6D404BDE4153C9827EB16D66C1D73A8143C8A2D3604FF72CE579FAA3C5224BAC48EA83BA848429 +9472007DE96466B5B29ACC7C03B05DCAA38A48BFF9F214DE43146AE4E04FA705421917F99BC54533 +F0EBC01849E396216B9F0794E6F6C6B61B52EF1B1950C0FB609895C3C55FF574163FC8B6B09E66AB +AED1810E698FF37CC1F926B2CDA3B48C7D77790EBD2D514B6F385D397F713EC3AD3954EA9C846158 +6031D369E8B99E53408A79D64C34EB5A56DE8A67DE91837960E98A66FC04DFA0EBDE21DB003234BB +78665B039D0A469A0221BD541AF7149A2A659C300132C14581EF766FFFBECBA8B58A5EB3F95446DE +F49AF863A8113D17B2E7E6ECDEAFC3834D4DF900E3475596E86FBB4E2974C090DB4AD61A737D611D +92B4535AC291C56AD8B1C031D2F9B505BB77517B737D70AB3723DB52AE2ACCD5DD2F617423ED3CC3 +9CA882EF41757BF7151806A9B8B0F312808863E3673FB54DE939B35CDECA7FBC4DC3BDF5A5F47D35 +E345916C39366C8B4F439CE1C6F1835C320BD1E67375B03B5DE18C93256F251761A4C8CEC01019C0 +68E34447BCC503B9571FE8000627A6B3DAD5854CBC0A2D69E5A8F46BC78F6A7B1422334EC7A98ABE +FE9B83E01DCF3C6C9273B346F3240EA225AE4A4083CC7B0EA141A0773FDE940768358EB4B13D82AA +304A1386D450C1C0C6A7D5A8FD2BD313F78F85248B5196241E31E5595F3BC01F37700A2DD3D4A0EE +2DD01A36569CD507130E8F5B1E96CB560BB7DA15560CCADF3B2C9804A11D9E8055C9EC70E48C1D21 +3EB756A1376F2EDCB7189D78CD3D6CA5865537EEC31C17D801605EFD860B0B629472690588D02575 +02C6F7A75B9A1C1B397781329832CF3EC43C09F1559CD562C48FA9500295CD3B0A790DD3FCD4684A +7C7AC49AC9BFFF36B39A9FB148BC28D37907433943CBBF0CBDAB46D3EA86DC8F81C859C52D15302B +94A9B51C199B7104DEEC9D769C2634CECF8B700CE9C04152CC59C9326BDACBEC4312DEED92DD087A +1C4840868D9F97CAC046581F762F75E8D24D6445370A3F1E0AE74A6478D9DAC37E7FA5BEBEC0A1E0 +81AF89C1BBF7F51E3E2E22C8C405E8671BA85F1BF0DF79A465DAC7EC07F731E00632E017D190A99D +83E27E5C2E63D7DABBA23B2E88334C63721AC5A4CBC5D45F4C177259F34C2EADE01FA008AF65EBC6 +01D8DD16436D86AA94C99F3CC0A2F87134E73BF22F108B825A8963B49C6C685474AFE4A542C8641D +C0375D7EFE9AC1168D9700459BE52D0DA399023E141969F25C0DAC4668534B6647EC85454BE945E8 +26B26DE6E3C4584B97A38E2B40A0D23481BCA78084FE80E00A71A790BF31DF468A435ECC88E60A57 +860BBCA3D65930186E9917CBD209C230E8F8255A7ABC7D3F043AE4D7AD63D9980BEDF062B7D5C298 +C40225B6D03F29A0339E0FCA02138E526F06B9EF47F5E7A8068A846CFDE2BFDEBD24F5A73A66C079 +18662AEC80B43246284FA4E2EE0D9AAB172B1E59A6CC46B801149D8C0DF6DEC9A55D8E1B0EFD9D30 +2FF618075944CCCB6831D336B11617107B0530D09885E5CA11A5F1FCC8D69D603DA16BEA51116D42 +CAB1AA1E4D7B9B4D79993F2BFE53EAC904FEB70B2D330A89780EAC10D12CC0C35B8399F218AC2976 +E57A26BAD20CE2FA2AE2363D3FD2A8A971747556F2959DA74A8963C20B504711AE1CB0D0C02457FF +2E9BF696B159AF031DD5155F21C0F5549B0471A3C5DC8918B675CEBCB23E29322B959ABC05283A70 +2E878DE8EF25EA760F3C5C7B7B49D398283DE2ED837FD59F7C22D62C58FE4448B1049FDEBFC8787E +67D7DAFE9774979BB3802254DA59BCC0219F98C219F84D995CA768B8B5D9D4A32525DFECE003675E +E4BD5D8DFFC11025AF2B468F9207B5B2B42349B98232BAC0759758C1F4A283405815BD7145C93FA0 +8F3ED2826655053A3C2559073D8ACD199DEA2C5BA5F616A2E48548B4370EC73493BA07E197165DCA +774438B0766867819C1154D1959FE6E01E6312E0AB91FC2E2BD240FC8652A2D456A1DE7F34EF372A +53794D4C4E050BF3CA5B7BD2F1B8DE93B4C8002485CB219AD2D029739FD3C81CC6E78EDF38723576 +1A57143EEDE5CC887F282FECD261F6A25D0A7E154ECDF5DC38E426811BE86AAA458577E5E0C5F0F7 +5AAFA9C41E5D1DC9D91ECD79B514F8CDF7A5F1A189470D35FDF4F9B8788879CCBD91B427822ED658 +389E981E0EE5F7FB87692A3E3E931DF8A1D1573E3B0166204240B7080089A09EF7487C9AEE2D665F +5A82F94C877FB5B0DC531CEBF1E71C6592CEA2401E4B5122E5091DF03D203DF979B9A6EFBA12E2F6 +B422FDF15D49AC0914D372D21E871DE65CBECD105FD4A3E4714B9CCA5C6803FA39DBB015EA8A88BE +7913502E562E5B170B87BFC8572DC9DF49AD63694311EF1334444BDF0B4CA3245271C1F7A4D7FAF1 +703E3AA0E1EA8D5C6E821B28707EE0C9B4F22F23796FE87356C58AE2CADC191F4C58E1FB58DA03B4 +5A25AC95DBAE13A293474217BDB214742B9D9D6AF35F70FED2891942EACE3E625E55FFB820543FBB +250A062D3D395BC0F219ECFE0D76686AC148BC41476A887BC494DDBD396BE200FD3E03CFA12EC9AF +6B934A283C42AA05589AA6B4A8D16946BB51F50419CABECEAEC5AEF9085C9989289E9B46BAFB6FB2 +782D84DE2B068F91A9744AAB237CEB1BA513E57E4C307108E993C972A3E0A898D5A8D27833155031 +FDB98863C3BE7FEF3004CBAA5CB60A1F2E3EB4D7290FF5FAFA088B1CECCB6CF51A58DAAD998F0839 +6CDFD68F5ABC9C1CCB8F6514107773C69C26873E889D1F79D10E866910E4684186FCD71C965ADF62 +39BA3418B313A27AD632300969B6F284519366ED85E7CD968D64823F8C59B5911A72D0A20EB72B60 +3A61E36F52F256FFCDF706B4560B4DFA5D918FBC530D83A4B3C01BDD3CB4572E24242D141BF9E775 +36693A0407D002E09CDA5B195BF1CCF430AE9824C07928A050D0B460F2704BE8F9E647A4884C4567 +0A81EACF7CC038643EB0FF18A376FF6F32B6FE4F197273327FBBDEC6443A299CAD4B26F7778A99F6 +5A11BDE047153E764039EDB251936AA43DEE50DDFDF8856519056AAFC4C5AE6F2051AF0579A9ACD4 +1D00775D7DBE70022CC263DCA5E0A25B9C7C4F5C418587666B2FE24816B1E0EC92F9074F1403BB83 +AFC3F1D52CA79C387BDEF864366E34C90BE52F7AA09935373A07E4E026224E76F9EC3CB9E7EDE50D +EFDA48248D61F3CEC880A3B8843306375D9711E58645F3625BDB8E87052DA67F9794EF4AF8DB0BCF +E00677C3A26907DC651BC838C40EC39E2B5A5DC0DBD345944A6C32226089D63C52490FA10B215AE7 +03CFB663EB8A47793B84CE7364DA1C4E7FCE32DFEF09490121222774915BA59C78C2275F829D15CF +4D8686B095C38C731B83D48738C25F40B8ADD487C350A2EBE846C3916AE384CB1050F9F5DFE09FCB +D9129C6270FD86D55A459618FDFA4F907E6B4746196BB717865AB378414029017551161A52E9D24B +E4F7EED553A927933D4ABC8F25DF607779A717909CB4D810DE8F5762581900E224E4B91598149BA4 +71CF8068ABE8744356B261600BFCC57FB8BE45036CF6571D9B2A95304933BD4F17215F8EF53F8E08 +1AF61FA7F9583C34EB5655CB0ECB82246959F09091F36989EBDD646BEDCA614B9A61AB7696B3FF18 +1058A150FA6EC1BE2EBC7F64357A3FF2A2B0491D2F4E0B970DE5B7788B467CA678039B5EF55C88A3 +84578D427FD2CB16C87B0BF0A3D37CE8ED43E0F049AF2436344D5F47C948C632C94A287509282561 +6C64C5D262FE5B24916FFEE982A69A6CCF888BD01D62EA591EEC51F4B7DDFAFFBEEA93FE08D736C2 +0129E345D06B10246A5F57151C198D407730713F32299638EFBDC01367E23EB59AAD42A83AB41B43 +2DB462652E29813740F4680A5D4BD47B18328FAE6BDF4200CFA4CE3773809B45E8887C9B2E423698 +9F6C48D64F5986F563D9A7538A8716082F81936AEBD0461E6F4BD470436D8B7656F0FDF89108E6DD +02ABDEF907731D458D690BC608EA9CED09EB1E6E64C0790C7A2378201CE997FFE0317679EE1D4EE9 +F91157449323E53B4ADA8096CD628B5861BF794543A98F2FA2AB54FF0F25A13DAD43DAF9394329B9 +5AA53CA32749FECB0B2BC035DD1EBD53FF9FB5AD8BCE06CD89E5568091C1CC314CFB1D9821D7F9AC +7C55F55E0A16E39A87D43148201B928F3C42B110FC056189DEF183745F3B637441DE8BD4C3C7EF12 +F4258E306B2877ADAEC63441010750DB4E6269A4C78A0AC01BB3603C386651FE814031CB5D8C1F14 +9EEAFF652A53E57BBD4C8C0CE36A84A319A53BC1E5FD3F1ED1EE72F4C1A9BF264B594062FCAFB22C +C1FDE3F2E3D3C17DD3F7FE0E15EBD812D550227C06D01127385374A11438ABD50048E17255FCD2BB +85122A6FB9B7DA9D5E9DE8A747FAE0DA45A1FCEFE92B9E70A5B2CAC668D4D07527A5C1403267D823 +048BE671F725CFC7474B44FC5AAA348420B2D7C23C6CA066666FD6F2208E329878D90CEF1C2E77ED +22D3BEBB9D547810B189F08920A27E7107F208591A84D463CE2576C70C3DFE6643E4EA93F4E1DAEB +41D46F0E2F56FC10C69AD5034FC9859D31CF27A3A1EE256C93111F81C11ACF1FC0CE20B90BAC9AA3 +27A5C85A7985B951519FD4B03C40BE637162AF41B2FDA68F0D1E9B7602FE2659D3D75955C579AC51 +DF6A552EB9581AC3F712F083F19B52A6C4F560F36C59CEEB0C996AAF1728A2AA45DCAD79BD7B23AB +388D5B0B64A2B95154B6259B730B0F4A72C8C7F7CC93C7D64D9D8810D1F63FF8ABD4DB89824E2D26 +4FDEE916C41E299211DB1A53256E1DB5CDD04862F034D9404B73183A99D3D13D642A663F129B6D16 +7095BEB4EAEFD03DF2FF2F0B6B594C1EE90FDB203DA89FACEE23F1BA3901FECC75FE1811BD701259 +343011262B6A0A9707AAA6316BC3C17F787BB80AC8DA5AAC942D90F80C5A3BB59E47EC767244AA95 +C63E50BF809998957936D3BF6ABC24B0A397258F9EB4DC8F65692CB023D9091FB180C69498CD0C08 +BBEBADC84A7E0016E8F8BEA325D924EB0DF82E75D2CC2CCBF039B11934363D4332C5FBC5EC556BE8 +5EE4E707CC2753CCC43D2ED50558E51A104221C9323CDCB0199B7B83454DE3FDC810D0F362C0299F +5DD981B31D8E3DDA284FEF9DC8F9C8DE138D3065437A7FE8C30572AD06D62E8527AD37AE39AAB0B2 +25F76A25F6C6505241ED73BA494CF923E919F688DDEBF193E188F8C4C154F21631080763B4D091E8 +AD1D2FD6649E0CD9360E8D1A67A5B5FAFC67547CA31C95A5EA8D4EB5D68B9F6D6532DB9B54584735 +9558542A2AE58C09F3BD2918EFBE1699E9C8F2C2A11EA4D224C726D2ACD4A8D8ABAEDC6588CF2AE5 +66528B94F55B823A2A1F7BE19000F3E7579D094E047075DF18C8C868760295533B26EB3ED90635B1 +29C17ACA679C3E88B06998CE5A7A2544B700229F5A6A504BD3E45B276471959C8A3F81917A534287 +39B5EF9E3D463B3BA7318448E2A3E79520D2D245A2A72F31FF7070B6E4624E3A5E216BD103640C8D +F387E49D732529C611F8B971073F17EBD2F6EB18F9B74A67E1997926DF178D4C9EDED435B9682F1A +279C81BB9F60DAFE125845A2FF3B02979E5481C78A45C479BEFB9FEF3CE2BA9BC46C77B50B03E48D +A6D17B76F06F3AD118371ADC69E178C52B5FB4B261C9311874ED07DD6D5B3226A005FDD7A6D53848 +09E7063F036CDEA41619122635E835D2D74CBB6AA9B38CAA4D819C26E95115FE0DBAB4198FC5838F +2C91B7A87B07D734C6D4F4F83444C1E90AA9BFC908A2BAC4B3DEF9157AFCA5248F2DA31CA87BD363 +AC25E9E77F741D4B2C6E02F04987A6F49D30E9038CEFC41BA172DD675AED8B392164411144E5B738 +F3210B0E66B17A13CB9631C33D44484E792A7C082DD0A5382F34C5637653261B1EB6D2035B08B4D9 +1FA9AB770CAF40A103629511F7B43F2743D7E583433DECFB19C21FD4FD0AFCC22A4119E77C87BFE6 +FE50068B22479015BE5A9F06BEAB4D37412E062A45E0CBCD7BB39FEE747E96306F79FC4F2E8942DF +5D9DA0E55AACCDA547DA19D30B8404FA121298B44C9CCE198C708C69A8D6BF17591C5C50D3FC5BE6 +961F7ABA8F366DAE957A1C3730DA4A5B4F035A9274675EE3BBF0CA8CE9D8349F50CABB1C3EA4948A +BE6F9F143592F1EA95404E6909A909168E3279A957AE1924245C356331A75E7008BEE92BEAA304BA +40B7C3F48F74D9018B3247DF50EBD7CE541DA48ECCB1B0BE51A455C3C13C279D4D8676078C3EBE43 +08748D52C9B041D3E7244C745B1F2F742D010A9E60695F3EC4FDC1050AC082B905D6A57E8F407A3B +472F731011A5798965B7B1A307E252FE02C8F79CEEDDEB6E165F1A94D7FFF18DDBDF79477F14E9E9 +3981ABD200FE7771B29D1D2D120EE79D28B9543818527039AC74085EAFF241B56D08220C958B5D9C +87C0C04A14D52AFD475B542D391BC54FF33DEF8D9484AFF6873BEED32DDA4B371112B523B6CE22B4 +0D1B416B64C9370F1CDF2C548F4CCBE9E12E21C36CC3EA52DA232DCFB65F66B22B5E2EC04852510D +5E264EE939BB67AEC4764B87062AEB7F680B40BCEE04AD45C7519EB3B6199C9E0E332661463647F2 +FB7EDF303EFEF84891CEBCF0FAC5F723A9D0476C3F8C092604C87FC69C7A90F4D64AE45A478EE8BA +2DF50FB93F55A3546123F0B0E2C1C40C98EAAE9F0F26B8F80FFE6E6B94B7E27D2884D58B8A119662 +2DF6BE608C5569D7864BB756DF2EDD184B90812B44ED4A32D001C31383A40AEEE9743651F7950846 +15C48E402DBC01C818D477EAC0347795CB2792E9C11E8FD4A02E194EED1C919D4598FEC003B6D9A8 +A0BC7D456047A1C0579453FC1D7CB2D158D466939A23D7A7B8ABED7E2777EC7487973E73F2266D9C +250CE30729E3C5223AD93B9AE8443B35711E446A3DC660123ED45CE1942A1A2AD0610467E081CE2C +8B92A6C82F0B17B5D2429E99F1A6268072C6B5AAAA6EB6283A872C54D3694CD825EB2926E57DBBC7 +C1663075E687A144E4D61C225781D80FCAE1497B442342B4A3F1CD6BDB50E31791CC3928C30835FE +F845B6BE5E2D7E3F2F5F085AA3FAEB45CAD0D76BCBB1ED859A9CEBB9F7457036F0BC3F195CB1A98C +9C8648F6583CDBB23894BC719D68C2DBD8003B10D08C8CAA40BCE784D7BFB4EEC9EA5359AC056E57 +B8B0F2EBCB1F4CE40C87FC7861180133E0CB6CE2FC4FE690756D327A2B5AE063E3021C0C0BD420D0 +56F0B941E6B36088A55BA11D0C35FD0132D5F48E5D9673572347171B4328D4807B972831C0D74CFF +A5638C145B89C989E6EC942148207D6DB82257585958034D9F9D4221C7C9F7013790DBD130F277E0 +BC88BB179DD09E27062379ED06F25EEA8B7FB33C35861A0034776E3813D2E9E5C10E227CC569AB36 +CB2D9DF2E7B7B44758F9DC4FFAD7A24AC7E9F47AA850C221048C3CB35A37CE8EA75632AE65FE3212 +175146FECD6334AE3D3C5F492F067F795E1E8FF386BA198CB74F0BB4DC0000DA383BC4CC3F070DE1 +7721431988D69C8B1A5AFDCCC83C22E16A87E01C6D3E79DC7AFA3DB0371B0866EFB8B6F88900472A +FEF1C4A878243C52D4E02E82658979731C841C489A6B97E271C4C93800EC7D91F93EB9B9C659A554 +E1FCE42A5EC65AC39190EF4B66DEAF6FC0569A000A9E1495F42F706FBEA4D32EB7EF11A648910259 +6A65CF899C2F322F5679C6D123469192A9BF1A7F1F2C81C554ADB97BD19ADB746A4F81A4D5559E60 +AB94C483DBABF6CE2F28CDB412D50FF3FCFA3B3DAAACC6A83CFED910CCB3B8D2C19590AFF4D75303 +4A6CE7F4156896A13808E0DFEAC547E69D3C886691728E4A35ACD575B40D721E8FCC5385A2EB28D7 +08101DC50811529528F5CB0C009BA7E3C88468E37768FB0D83895AB54DB2DD5426562AF9D8AF304B +F6EDA54E9C92643DF926F5C3578269750120302A37CB140A18BA56BA01108D4ACACE8FEAE640A6C6 +958EF156B588ADB0EA5F3B0F37BBA12B7BCB221C811415387B024B7076FA4403A3AD6EBB5D9C26EF +EBDB7ADE7C60B444AB9F90EA493B658B7767AE2BE649BDBB3FE85F460F1ED137C61BD95F7CD3D8B0 +15CE45138538930AB62AA0E54B4CE1A5EC5FEC0A2B28B345B67089A4E4AE14D2E1F5A9C8848DA688 +CA298F93860649EC3AAFEF3E820D86988C8E3E5A4D4BB937791827994AA3E81D0BB3EE115EC36D5F +B9A392D09E79AF514D11C7B3A03C9F9C13355CE79E119A19177FFDCA34704D38118A8976D1EE5AA0 +2D14FEB1414419F5E85244ADC5C0A765A522EEF36170064BB19FEE3B5F7B441E4DB967DAE0BAC2C4 +8FC6A836E0EF5A69F073BEE1699F55E9C757EBD6FD8B514E2B49D6333815B7DBD1E0694695FCA3D2 +1320A0C4B852D9706DADD8369A95FDD917328BE93DD33818954DBD2C212D2CA81560ED5BC284EB04 +7A5F389E24E43F4FA8C97FECF46589FA7341076555CF55B1C21B28E0C1CBB00AB8B6F67472F27BC0 +D11148F407824B0159B5188D4BB7386FBDBF1C0FAF34721B7BCB5C0FCB7C4010DCB6A1284E9D7883 +9E3C2111A05D29AB7997073B590A81C6168020F1D48951BC7D8476D5BA593F4F23CAC1F9BB0E091E +84B4E99E5C584D1370DD12DEE8DF16AF8BC6B7B23E2FEABDB7F32779AF8E2B5094A6E9B7A7225F24 +C43A8E5D2B977E1E19E633C26771E23017ED233DBB02C64F8CF03992C6484528D0C8464B46F24F9E +8380F385D5D01B8893C67FC103498983CF939432AA380CA576D09030CD52FD99BDC3BE16C7204CDC +3365BF76294A83A1FC14A236F5FE5321904E779B13232A76F8FE521F425562678436359C2461BEA5 +AB27209541F557AE2AA60009C9CA0A9FC7898C14306CE35A50017BADEFDECBBF94EE2905220706DC +806409EF87DB1D73EAB0698AD2DB72CDCDB293E7FB13C94D9FC87E74502E6927A212F0D7D2F2D194 +64F7A66AC07872E18CB1DDE8F11835DCBC5C4EF039333FFFC0FC1456DAADE7DAE3EC2EE0D3415B0C +ABB69FC5006F4D14A4EE1A5CA99AD4D5E629C0DD1E0F097B5B93DE2DD001A8C418234C9C45E8C13D +1AE04E9466DAB8CF1ECB88A4E059C111A6468D2DABB90DA79C7C79E94DB28F6968B1A632F8C57D9E +565FF91C6916026FFAC0661856B9FB8DE9C81661816221B1FC159CFEF1751E7E403F5F2CE32529DD +540792FC17A12A3DCD7C50D38EEAADBD10ADBF5D8A82442AA900CE6150EB7A4639DD9FB6E385B2FD +093493DCCD9014B23EB172E21AA89643A6CAD1093343D85D81261972DE0ACB16A4C6B5F0BE4C978B +FA12D3CAF0134F9EA49F6E9687C8F99A456745EA252F0BA9968C7F9586E3DD841AA92DC7705BDD68 +2DAE41518A09DF0E209F321D7FA3417202F4BA76A984DA3ADDBC58136885362F02F0A24EBC439B3D +BBDACFFD8498EBD29F88F016B1FEABC10785438EAC860B554525F3266097A675299AA0967BD3B7A0 +EEEE3FC578D1BE99D3533BD91571AED904BFC9DA1A1451FDC5406E1CD614E0C7FBC733563CD6CE6C +C31E9237CA153F1F0411114361D731636BCF98555ABF12848AD109371A42B63675A4130B81E97C2A +2EE2BB5D8FAE2640156001AF0F55D9D5DF8FF23C8AEFE14F120000F14149A36E5C94CD9081DEC277 +C2C34870D05011F99D48B0875A5FF542F067F7E9880109F586BCF2B50522A1F23ECE44349E539E70 +F84E207DC9BEC7CDF856A046F1A03226AA41F541719AD1AF88FF211E57DD0C1275DD0B7B47440DA0 +89B98C6EE92A7D94700B83CEBE19EAEDD8A615F6587587BA8BBA3CE3AA5E8EAFB1FB0F486BE3609B +169EFB178A4292F4C0378AFE5D24EED1CAAB514DDC66C696D8E37F294A6579131DDF5488E9436609 +ACD750C3DB0A940C84FE022B22ADC2676F62E91E8F891225F891FBA537679B24547BBBF35F04915D +20B11739F620D18B5B216921D222F15044368569AA302980B9225BB839F494588481B94B0C724352 +B2DF600A22B062561D86CB8F81514FBDAA4F8A043A0265F992FAB71FC9124A45B8475E1EF3DF6B6D +E35CF329777D45F08325E8505EC0D979F542807AE77E57E453525F23BC59A50740371EFA98678AEE +6C425374AEB745B99DDB5D8D908FDB551FBC0DB15832107BBECC4E11A1A8DEC69358A574A2ED46CC +31D564549EFF23102D92BFDCBB2BB985F78F36033E34F59C0EBAFA3BDD71338736464CEFDBA91398 +33995EDA4207BFD4A9867D32E867FBEB7DE60D132803EF9347CB17BD91315484EF6570892297DD8B +7D966103339535E28A00CB1EECA4A9775F60A9F5FC9BD8B06D78FE8E6318C31DA2E847E3F9CA587C +B01AE2BA0A2EBDE308314413F4F230A758184ED60D4F71F6CEC22A93A01B6C54E0449A3860FCA895 +4A347B7588329A80974ECBECDA1070FBC055666375229F13DD995E99265DF870BC8B8CC6347FADBC +1A6AF64599271A475B9123493D46BEC41289BEEB67EB97A8DED7A9C9730D37C65164CFBDC22E5CA5 +89D2E7954C7136EF4E084C43A6C7F361A3E96989239BDDB9A593CC2A80BA16DE9EE90E95CD39393C +212AB22EECB677FD36D34DEB46C4AD0D21BF7E6D7CBD0C8083842FCD87B18FEA7CECF939987E99BA +34C214E44DD84C176C9CC5A4CEA76D380CB316BB4EF9DE73D73B4AFD4ADB54451591DEF86621D138 +D5A0A29441502BF6C2ADE671CEC3CB5CAB903A657EB2D70C943F976C110E46C5D9D29BC00A875F27 +38E5D22496A43E096E009C5D3CB724B4CABB32838DBE527F83B18CB457E57B092C302EE557FD4F00 +DB9C56E66C9FDF4EC9FFAAB85F60D02BA79694FABA476A199A0331C30A78A92E10417BA236E23364 +8174C826331DC1BAB87C5F95027846130C6A2B4027930EBF9A97BA1B039D386FC51C302648E25980 +212F6A582CDE2778C677A01FBFB3C5D1B8A374ADAF6ADBF7DC94075F25ED66D440B3922C5F255FB2 +3FD8F6E21EA65B1D93BB225684B50F11310E242B087575973345B229BA62C1E2C35BDAEC04D10148 +F5B2F3BCF7399BDFDF1F3F79119714AEA697245BC647316EA157484ECB951BE367234FD02E8B1F09 +1AAC3D29BF282DFF4011BC0CBA8E55234D943DB3017CC7A766720BBC29B2D097A956C0F1067177F0 +12D42ADCB473CDE8D1BA35B4030757FA1D8211989DF3BD22CE5D501C21EF8708FB3449DF47D88650 +9FF7B59B76C0DBAE443F336FEE2D615D7EED1C284F14335BC8A26BF4621E10DE9611FB2F1DBD52E4 +B7565D8C65B54EA36D508BCF0C578A49A2665227CDE1F9768EFE847F9D94F1BBB7DB83701C232198 +5C7283D47B2E40B27A268428AAEFE75F6B2F8764A8494E5827573758CB9CA46FA93208836BCCC8B5 +564A69F5AD882052AF1C1417C3FA7F580569528682C77080F3688B65E7FC24D2A3AEB61574B4A321 +5927281544DDD7A6EE0A3E9388F8F631CE7251724DF70726E5912DDCCC8C652DD6C9608F8462303D +867F589DE0F2F71711B35142EE6EF93B64D6326C4DD7DC83278E057100EE772082E6BA368ED91A55 +53ECFE2293A481E42F83BC8F9148C70EACE91F7B7D9CB8A72415BDB3AF66F68EA733A17ABE9DB005 +3BF148629132969589F38D30EABFA96A01FAC72650B5A6FF3935670198A1EA33810A9B11E330EB8B +451F24F93544263436F669AB5A90A53B16CCEEAC36B1445574EFA7E802DE73522BE725E68704822C +B7D3912717333367895BBFBE06966A5CC653AAB5E9B3596702086BF0010085B900711932A95ACF15 +CA4DC45A754EA334E9EB84D6FC8E3FC4F897456BED64BB93B593549FF0D5352275D8E417172A6664 +C5E0ECED1019494A7ED49AB0B965BEC1A82E5873766BB38D7D856049CCE2FCA65AAF61E961B60634 +E2A69EF059754C9D8163D87F928C222772D070D83FEC6FA5AC734AF65E40BFDE521F7D9CB1650FDF +64754BFF21EA3FF0AF7611A93D525EC9B28C51AFECB04E7FC8323DD6C9B0D8539A34FC3CD8CEB795 +8E8EBBFED4313C77ED469C199552A9FF70BA5423B03B6148D4EAAE17B71C5B39DC436AC53D6BA8A7 +AD81AA8B02335A8B2B11E9F4FA913159A725B8AB60F52F1A2EA50EAF4D56656E615BF382CC68A690 +BF83DFF24FE986570ADC0290ED1A37C1C2AD469CE789E0EA0BB5CE01020100E729721AF3B5BADD33 +A2DAA6C33EB8F9064F5292F715F820B4BBFDD56F76D42E7A1A068C1CBDCE4640082F6E7D582D1939 +990CE6EE8D270015A2C461798B37DCB5798EE9F7512168B76D26C28BE4A49A1BF96C89D235F21A1D +B6A96E5DA474D0B19B808D13D7A11BF39EA8647499C410ED9894A1ADF33D41B6FC2E614D8087F4C8 +4E437B136F3CB32DB8393C49177A0675A0C9E7EECEF448A97AFDBE840FA01FC7E5F2E8FECEDC1884 +84C312E8635CD79195475DDBFDD4D38D5A0246DE2C7F21608F8D2C0DA1371D302E941572E5792A3C +F4E51A33228B93A814D03FD4FC223C314CF3714BB3A34BD4F7ED6348577FEED9DEB082C4049E57B5 +D3CDB7F26629E9F3BA36893E09E3C7463D02A22D7056BE76B87763260E46E48BB832B7EE13F8DC05 +37EC8E81E9BDFEAD8C27EBDF1AD706933EFD11131E12814F236EBB01BE85B7F1B2D627413B324918 +D247604F56EC128909873FEC3857028BEF76A3494364C2A7002D104D486236C30B48E2B75D851C34 +EA50BA7FFEB4E19190898AE21768C157C0CAC628A2181A32796FBC1A7271D2473CD88E5395DDBDB1 +FC3AA8DF0F3D588637F19A8B833AFDEB5F655A8838EECD684E2315B72C75CEEFBCEF94344ACE8D6A +DBE355008EC72FE7CEEAB01363A895F4E73F867639BE0A0BE67333848816B05B419221BE8F9066C3 +62C23FE85B7F392930BFE4C12B9526FF2FDEC38F23A159ED61A0718E7115C24597D849FA76369153 +54A40C965D4D72EC94DA61A03766AB39AAB684E134FD1407A5B1B19BFEBA52AA0DA5D99CBE5C82DB +AA663711E6DEBA180E1D4A39C320516A4350D296BC19BF1BE054859A0889C7E9727A021F3176FE62 +0FB0C837E4141FECE531A950C03D319E3255703220B7185BD20FE5DBA673F8129AB211EFCF36EE39 +4C7E00EB0876624BC840FA86E58B2F584754CB6BFDFD76810E300741EBE4544E5AC17413ADEB21C6 +2F66CA4F075C32381796BA709782DE34A675B717A2C7F6D88104CB924FDE5DF775B4F0B68E0E2E5C +2F788BBDEAF06D8E1FC2105CCBBD5827C0B03FD6CD64F0D073F3192D5F94839644E5EC6C5185BADC +F04112A65F49A8C83174A9AE958E76A2F5AF469E8B76C833782C5FFB8BD7B1BBBB3EA0CB7C9786C3 +BE2ADE5E7AFA8C8F20892659A59BC421E28845A108E34EE17864042EF587A6D67DECDFB3F510EB40 +D2229585347A0035670FCC76C2837A4E4D68304FE113C539B35C1F0234B5079B8E32934546982978 +C5E4DF955A454EA263C3CA5D7101F31A318D82A3F9FCB5A8AFD7A65209663B0FC9DA400B26F285EF +46D0E1EAF8ACB1F1CB805E3986D04BC585073FC64895E4DAE1CCB749BB439CB32EA91176D5C39C36 +50D10AFB9C9884D5FB90183424CEE67EF2175D01D2478D67511EC9F54F88763C152697B06D948BED +49240096EEE3D06AB4575E8E8B2CB8263B5BCF4FA1608720F52B675309833071879DF52C3EC2871D +20F398B5CAC8F8A4D41D0F1D47584DD90DCDAEA4A1CF160C4B3BF1AAB890B5CEB6CB3488672AA68F +BD938281DBC1D8BCFE92FBF514DA5358443CB6E0147254E91B38CE6787B2BB0DEDD2D38F5938737A +977B5EA42892520C58F8FBB53C994B57382379E9490F0D6970B980E1BDF8CF9F4C3C5E0A18F66E86 +EE93FFE7FE546DE50F41364BCB3721B637072571FA1779F1D672FAD260C16D7F13CBDF3E4376E7FF +56D2A710AC5AC35FCBDBCE2C9C17E523BBE6218617B13C1FA6679B308979AE7C61DA6E68369324C6 +CBC7DDEC364E5A86707266C0B459EE7B2C03FE584E529BFFDCE98C90A2F3D9305AA74D3ED8430DBF +3A49FE2ECFD9C4BC9FEFD22618FE9C8A973AD072AB6F713E4DF02DCDA7AC5359B2D652013E131B76 +B3ED6C75FD53BA58D862846264627F6B9E70D8800F6D9B32242B747A67BB2B45675840D34F852AA8 +062FA6B01E31ED24DAE02F6CF788A17F7B9368175195DB0072259CCE0FFB2C1035C1D26E1777CCA3 +D56A827C3242069E76D6DD69B653768614B9ACFF16567FEA61508D51454BC02F6C60F755AEF6AFAE +3536BBFA1823F8E1A53C41124DE983E51CEC92AEF4F99785D554488A51C20885346D1F761DA79017 +940A0C557D93F1DB6B3D00FFD61D08E96FF3AFCE5FEDF545CC9F47A2B1BB26713431D6D1E47FD6BD +6E3C668B0368241F0EBB5FA9C991DF79890E52E83A3675EE699B61BAF869DE91F67278F510061C6F +E41DE2D883F48CD0E068E2A652B244128D82E5CD52F35F210DDAE3054691ED55A7D99088AAE8FB04 +F525C2084AC09F5EDF80A4EFAFE981F74C0DE9D194320709B3464F3FF2C0F6AAEA6D973D9C323F53 +DE3D741F698FBF01036716BBD62957CB32CD81D3A2674560FFBC5BDC5C6E4F547E589AD0B1CFE14F +5E17FED1C4A8ABE4E67CCF8A49F32C4C6044F1431E1CC382E7758722A6D0DF9ED23E51F8AD14D11D +7B6428E27443715EBA4E9C05D6F238378F9498AEF0E7EE4FE6856622CC8E6ED141EE5F109E343CB6 +695C4BE1E0F66601C27975983BF557C04ACFC19227A1AD7E6C44C00529FC7EDD7F886D24B7E029B9 +C395260088BBFB96972199A7B32796D27257DE83A7402291C14FECDF7998C5C96B1EDADE0280F856 +8A8F5007852EED303969180B3329917973C2D32C080C9765B6BAB0673BC7ECFDBBFBEA980C263843 +39B7F1052591D91667D4FEE413AFC23DE2D4B9DA742F4269C6C939F5FC32A38040730A018155AD73 +3F231E4D5B9D01C03A58EAE7B5F590CCFAF25EDC8552CFC8D95C60EBAE1837D7A97CA137E9D4A4BD +2CD34AEFD68D64B3F4F62326AC429921D7FB3C235184FE0899690A0B775F1A566EC29D5830D32372 +6526F7E7F5AFDD71B77E07613DDC4FC63EDF49051AEB59E6337AC0A4B6DD872E776C9CD0CCB86130 +5322D816732124F5978A86C186BF0A0F88E733CE38E4D7C1BA5378C5629B1EFC97806059990ED42C +5CD183BAD7E94070E4058569DA2E51831FFE0D080301AEAB4350BA290318AEC582C78D05DD92E5AF +B4424EA808629BC972E68F4FF2489C245593F07555CA6A2B25964794CF31CBD3AE5C229AB9B8C298 +06C01D116EBD0FF0F159ED2D3D7DFC73EAB4910BFF5B0B0B587CD9EA6E6FC45D63C09766224D8346 +1F0588140B258B1729F70BAE7962189B1554483392988CF230AF4077193E53330519394DD99BA135 +6D4730AB221DC6A66019BFAE564893DDAD7B177DADD16ADD21D396CFA6C3DC818052E2F71149FD59 +4A16DE0C2FFDD366C99B486C55A6E991E4D22CCB15843F0C3363676AF2F5B2D1B7EF66CCF2F12DC5 +0D63776BFFB058D70A9C76DCE96C754872D72C82A0C33F90D49C935402CDD26B6D743B1F43BED5D8 +B539424849C1495DAE73044E885A7D0F307F1816DF6244A6F2D97BFD4E200E93F69B08AF39EA21E6 +E347A47CEEBF803F73B978ADBFCF056789BB8E6E2563DE87DD9A8C877157B934102DCEDAC54D487A +1BB2694F0034093C48F10A17D32E2BDD0C723CAF59ADDD1BE373AF8C9BEB4415AA5AF36310C31F24 +354A53C0B962573148BEF91D994FE3F3D8450DD4D686725799F53C373A0A3E3C060C2E1A3E800504 +9F26D716E1F381B9F83125E4683264A07E2D8938F605978E2513DD2050B3D8A1012797CBA8961632 +BED260916338A812AE751C7B657E086A0C7DDCD3BFDDFF3E48B84751925736D1310C4910FC114387 +F3ED7FE163F91895EBF55FCB425CEF5729D99BD8F2C072E36C310523E75CD8E5DE49C031C4263410 +9D56E91A46C8C8E89FD92012A00C33D0DEC52597B5C6933291A7BDC5CEDA95DCDA5600F9AE1C8250 +54E7EE1067458CCB66610704C58E4A4FC0CB5FC933D0322A716B2CD430A3AD48DAB3D4CBE9D23F2D +092368CFC4E1F5495C133A92942EC62118D45C17723646E69407B4A89DCDFD2AB3FFC099A21D9D29 +741D68270629AA3A414FE58658DC9170C247B6E23F35C4BC5FF83009F462F2EEF4DBAC5FD158A658 +57F9B6DC1F5192DFB169DCB65621CAB2F1B07BD22F4155A8E9E2B6388D430FDE5EC1C834D22EA035 +C52E1E34482EADC36B4CAE902AAE89A7284E62B3C84B608D6BD05F75BC31310B2DD3B2C08A00E073 +7F104F03A41989D5F6B9A2C38B22F1D1803EE5D7A4D8DE44E4ABD496A1DE0C0E12C4BC96D0122846 +3F0EA9CE9509FEE987139F3DD3F9D0DF4313F555BE85433718F6D05F197C41A9D9C7A8B0D2740196 +82D49F58DD5F66B12A6520D9F226D1DF1F1B65CDFA261F980CA25A92645B86B64606293F8BFDE364 +C47D2AF2C709BBE77A70A5712F2CC26F3D66F5BE2C307A48E6F887F681D30121E32BBD87271B5DC4 +615D28C309F15AD263FB37424E56DDA6E17B998B45BE6C7FC6C28E3394A8764C9EB2DF5C06626593 +B5C665D550D4600172791CD208AE9F37BC082B0B242B0A504B751B18F4D7495172B697EE217834A8 +A4FB7CC16D6F9E8BB400BE8AEB0850960283DCE725249FCC4DE97D9886745AB6066C3E2F64DD8AB7 +9AA11667F11188D7965DC11EB760B772E282DBF13249F31986AC6898FEBFE23E3E8B8D2C33E00EA6 +FC493850ECB2E6D831D1EFCA3C2EC8EE2E394599091ED58BEDE97D7A43B6F739EB0F845EAC1DF6B1 +EBFE876009CC5D804B15ED4B56761B3CE1AF59C07B49DC798A44532297AD73D5101ED47F36A3678F +818297CC27F6AAA2AACCC9AA9B6F5459911D8C56CF499E390AE607F3790450B2B9C9BE0F006EDA0C +715B5CA0481734CFB0597478E7602B0D2C1E4F78F03C68C17C70E4B42D7D2D3C95CF40F73488B371 +8E2CB05A549944D86944D78724E266C3319AF89AE430E777E95F0D792B1C654306E421F3D63A26B2 +1E74B6E8B21B2E2B9DC596D013CDA16D08E65E8F24A84B12B2BADC653E6E1110DE2E709C1C1BED13 +707B70A421B384F20CA7A9A9D20324DD383F28B2D3C7A9C53F5D4C6B7C378D26DF11CF55238BE1B2 +4FA70DCC178DAD3D35670FE4919085EB1CD905971D76A368FDFCF9D2F0A23739851A3A6D2E02D65D +54DEE69ED5D81315D3EA5E356F94EF256DD267FD1E1A9EDC9CD63E743F299BCC4A4506233B8DD765 +2CA067F741603F93250C087D368F9E9CC4CC1A6DED567487C05BAA992B0056A77F630A72008E3946 +15A9DB24FE56A956650EC9DE90A6C2259189440247970541CA198748928215C0E132A81AA13208D8 +63C1FE817F70CA573B54577D10B73100AF8EA088208A44FB92ACA314AE5879706180788C17BB1D0B +81B6B95A1C4E0F9EA66F9B39BFE12444A6446691A7BDB03E0F03D9F07A10A7598F2166F108529F34 +CD90E601FFED3479ABCFCBDE8F051C348E48C61D95B00C59EA1287423F05666C3D36288844067E83 +E14F6B5210842C742B89F13ACD126B9FC50ABE2CA7D7ED513D43B6AC7F41EEDA416BFFFCC5C844AB +2D23D4DC09B2D510504CE98D02E72020D9E669DDAA344C63A1B75632F912A1C0DA3885DA4AF7E243 +E4A4C6493D6595BB6D56B0359106957259E59E336BAAF35BD1CEC5CDE735272EBCCAE8D4904AEBD2 +B32610C6FEA2B69941D6542ECB44D71092A3CF067708A3D087AE99FF29671AB7DD8758759B971A08 +AE1BAD78270D2FBEE37AA2DCB119D72F6C7B0C8509018A70D0B0BE2C6830EF8E0B24B1CE1141EF87 +3A4D7DCC501F808BFD94E4DC0F2915AA023076BCC8006490A43685EA25AAFC187302EBDE7FE1965A +04A5A398985D29F08E085127B56B057334D88EB638A4DDE64AFD204974C3939536B1B66A54B4DB81 +151853915718F70813F096CC1B0EA25E363B49264C2AD17158A4489F91453FBEDBDE15D7B74D7F98 +E81DF23251785D58295BA297F295AA6248A912CDD4F1111E6B628EECBB5139709E76EA4AB743CEC8 +26621D08E6BC64691CC90B3C3C1778931A28D3D5B1E20E96C643316613FC487C9B604C43463FA453 +3BCA1236286E6F5A6EEB2F1D9C34BDDE4595495A365F88055D9268541CF1654ACF478D384A5496A8 +772EA1402751A093582A6625A0A44816B5FDBE166835D598644296249B92CC90AA3FD6445C9A19BF +27F59CB0616C7306070F33C7DF4E1DE64AC8C5BB2FFAC1EF2B1B30E5A0275E6004CF64BBE2C6710E +DCFC3AA4ADD60106334708862FFA6652825BC84842736E47AE6917180365C75B27505EED3C6108E9 +898A780E20C3F606A860229AC46D0471ACA0187D6D539A1B8820F620F72B41AD1D3BF3834BF48CA2 +AFEA8BF535AF74C4562DEADCB63D2F5C7585722B77C989342D190FF926C8A5263B4F25286F99CF6F +C62EE6E2AD61C82B29D82468AC10FD27764278E5558CE8B41BA111CB2F040914451A480C93084237 +CAC8F66BB7C6689F340B8ABF0150E06D5B1177278A4C08742FE22F42C28680F190900344ADFA486D +59718C25D37275BCE4DF981AAC35D2C7E85C72A0188B8953CFA516FD545AEE0BF4B8BA301CFDE214 +4241FBDF3D204E3D2823301572E23F204C97305A82401660E12926EE7BA6EA1A81FF5C007933AFC7 +3266FAC4C134ED818A48E7DA01C71A46335C845F9DA5E960B25339D551582B375814148D94CFB781 +FC56093827B78578A73D4FF67B6B87F40CFA5E3F4325D9108CDB64BD06427B88C84105187316FA29 +90B4E3E8EDB6C78ABF164F4A9717D523794B2FE772A04DABBE688CCA977090979B5F47CEB90A1DBC +167D305EAB231C9F4260C4AD10889CB785169902FC0BED78DA15B8417453BB65856EA0BEA5245BA0 +573F623D215F6C0CF801851C305B355D26B52B0B343645FE25C78A3526841EDA480919A1BBE5F56F +C10ABEAA3E1FCCA7C43EE560F067F1AA2AFD642F769D1ACE8E2AAAF38850F0D757CD808C921D716E +96FBC07DA7860DFA70CEAE2888C0ED3CBF9586443532B68DAED9A926655C157A416C383A53D8F283 +2A4E67468112A09ADC837ED8EC95F70852921F50D4417239FC42EE3624CA97F682745CC5E76CC7C6 +7BD99F2180F8C0B7FB49539C8CC474C25C0DDE491671FF329E51BCFA779346D4686835A3AD6633FC +B5E0F67E0CA9CED8F215BEF4D240453EB2EDD6ADB22278AA5B985FA140C9834D38753DF2014F8C0E +E6DAD19E8FC54C03C1F6CB0F858986691D99592562CAD95FA0A5B2ABE4A8B54B457D42E8C33A2D19 +51C0419A72FB94FDA78ECD92BD2A1416459E9DECA9469F35E4C47DB531726DEE8F203D7042EDB32F +025DF3D582547BB1D45F7A5B70D317DF4EBB16E36B0D798E0932FD2A85B04FD67143E4B287A50416 +2C1F5A037CCD780088C5476385AF8168E12D97D44B0630621759173C8F1E3006B5B1C6D7138B7EEF +C3CC5F54E24B2C3CA7B41AACFD25E554880AAF406EA4C3C6E21D3B550B040FB1952598A7E8E6488F +E38288B2AEB6C4718338598A2BFE4D2B9D14C65732DA304C16FF3E1F8F03046EF095B65FD609DA87 +EC24A69278BFE65C905CD0329F6A486B8525B7EEA4F7AE56C2633CD83543269E8ACD6D71F500D82F +DFBDE7F7F7B1AEE67328549232E26CA55085B6E84D9E2E7F74068F93A90C4654F2F396E57C5F76F7 +E61CBBE523DBFBA6E76638BBA3064DA025A79E3A294FE7F1CC28A3B4C57DD6FDC48E541A85534B25 +E1BC11B4F78019457239EAEFD4BE9007D205F1D985F389DB22400B279C10948551A6B4A17FBDA0FF +C9428B18B43DC76EFB15FC2182216F1B60B4E344A03AD6C00F141EF99F89F24C819C3E32877A927D +84C2D006940F39CA8B71E5951673EA9BFD1749923219DE38929ECAA9CE43B06CFA7DA1BBEDFDA56C +61FF6C24F40E59B13870D5FDEB82D981154FAE5D6D5152DE69339359461A41A9713B6BBE47E868C9 +33CD74C75DB71D13BAE4DEC85E02FAA14EAD6C0A253B16C79514657B15E68CCFF9EE6AA385CFF9E2 +C53D9AE40F85C793E4E8FF50B2B7420F4FE69807BC5F37C3E300E6B3C3549D1D3246A2E70F091054 +1135BDF805E0A698E236B6496702D061241687B7B8D1A0E517DF0476DA09D89667A7AB375FD2672D +CBAB8124E511502DDBD08BA04D941DF1CEBDCCF7ED48405CBCC33774A68C5212FC6F132641FF413C +984F8B43BDFD7B1A2A3435F15AF07EF4970D3E4A0BB947C181E9CA27CC14A35BD1BD096875B45873 +8CA244F88C28728B74E25CB8C4FC1095A56CA75E4569AD3082EF194ADD11350DB3B74B96761D4538 +596FF7243B1E1B724716A144106E080D42036444FD472998460CE9ABBD05B42AF9389AC452BDBBA3 +A13A96890025789F16B9D92251FD3B3BEB2C61EDDB370A20456E3BFE5F4039E2557C451C524F8087 +015BAF3FF05F51869FB97512968BDB2B49589C1C7AF1E085250A47657465F480B7023E24C76731AC +0EAB6704123D77977D3A2C4C56B691346EBE589C619C04515D34F81FC6A17527D5D8319013C5D4FF +27CC3925E24C99231AC7FB9EAF0BBA482D3B75807AC85D03CD09DE5D9AE0B07B7A813F0449786500 +0AE8A7E00080300F0AB8C399057EDDBA273DD2E1B2A0DCEFAD3B332E6D4AC1FFAD846167DFD70E03 +46DAF84AF292D4F424256ED5AC4E104F80697050D50844A708EAC9E7F7784FD01646F3BD0C595CA5 +1EE6BD607D254E78ADDC5E15C3B6AC4940EC865A5C23105B6BE09EA09F2C05D6D76960A843B81EE4 +33977FAAC3CBDA85CDD2F4DB7C28293A77825635992AF8F3B38B4480D9A139B1662345A8ABE1634A +77496C3F57597D2985E9E54717AB2E99CA35789441BCDDEDE9A9E2106B401D9684ADBEFE40D607F0 +75C179E9CC03E59E65430DB70B441D43DF03F2AA6FF06F224B6E455B01C64FB89EEC9103E48453A9 +749B4D602808C7E408A8903091D85E06AAF635D0D529C3CDD1B8479AC0F4208C284BB678A547F2BD +77BB17C86D4560434F7AD1937760A6AA55B614CFA9FF8C9C96561AE6C8F2121C4E20237428BC51DF +2099B6C49E3EFA18E6D439E6E6981E746EBB1DC461259D8EA0F8099C47CCA27B2D982B72C9A07CF2 +1B3C05D6E26E6E286E348B8944078E24809F9C5F3D014B4CBA02533F5621BFBA1F0EDB776C634746 +703C9F73BA89B1960A496420C68F54E5B901A6D733D7ACC79F275FFFB253F389AA480084468BB34D +A1E797E43B7F6E8CAF5E8C93069A3A2730E57EC39B677BB73E3F07C2055599F7062E53B37A5F0099 +907D2ED87FF7A82C95FBAEB888033BDFD67BA3A6031A4CDC56CB1E4CF5B06B46E16D988BECCEFACB +9E1C037023D7BF5CCF5D65AA66A17AB361BE7981F132A578F3ABFB97960A6034F052D9D5AFDC0679 +782EC90F240F943A5F9A3D969ED7399254FF67D89DF668F7C56FCEA1FFDCF20481474AC8495D3AF4 +B6D7EE093E369C057F0B70858220693B398ACF8E8143558132E4391405E30A73937C53402E459F4A +A3539CF7A99A3F51C0307D045DF8B77757E92EA2F51BF0BB4F77D3904DD355665870C2B59F1ED7F8 +4FC71FDD7F0B6C5D3182DB77827CA6A2060D2B8C83C4EA4A432EF43A4D0A952CC6CBBE52A9F0CD66 +1A538973DE41FFE9C5CF55F2506B9EFEE51FBAE5E63BDCF5528499A47C031163C88D3022606784DE +2F46A9C9235AEE3D4F71D4959B0CFDC5B7E78C8C0A8F9DC99440C2263DBACB343C5C648577F5610B +50EAB1CF7FD02419EF3941C7CA0B0E64EBAD4B2CB05A0793DBC38F1946D44767BD287F5E9779C611 +CA0DAAA1E7393DBE0683C8D3455CDFEBC0E64B54B737E298DDA605227C0C4BBA87AA3EC7FA6EBAEC +39E6EF2537D5974391D31739D9FC42983D81AEE44711C823F35F8E2321AC74943871739D2DBE9748 +FE68592263E7713F27E0D49B9B5CB7A4E55DE54E6B800D15856450FFD3AE5F287B12AE4F438B20AE +9E27E6CAA00F3EAEADBE08432684FDF9931E925544A680182602A3C1997DE5D0630BD5A010535E66 +E1C123013D23966B3545C7431C39B97295BFA4099D14461004C42C85095EEACB9B47C593BC6DB863 +533A8619BAE09095DE8ECA432D4DDD49AA600D277E75DC3F5C6631E2A05382CB007825FADB77438D +CFA78E252D79B6A196D5164C2FEB85D75ECA25FF80B1D97FE10E87960CA0FC47C41D3A213BF141B4 +8BC3AAA93FA86245064668394665BFD52D12C3BE4CE39EFD8111754398A944C3FD1AFA98EC337BAA +AF899D35E804CF416AD7FE45FFF13FC6354007501043F98FE8428DE8013901BA6A28711A2CA85A27 +0BB135B72F1D5026E8217581860729E94F2F1878A0E96C59E9F62714FB5F8F25003DFC7347E99007 +8A9A331CB3A6A535BC61866F02513DEB982C4A13ADBFBAC3FF70A7335F40D5489E48E5EDEDEF1619 +1973D932479C62183B0E25EE8C4F76D4F1AE45DAEA4A12AEDD9EF81D248E8D19F8C8A5BECDD1EA1E +98783EB7A38149170851B1942C96C53DE06DEF80913BFC04E539EC67C110498D15B78268853E5C72 +F485F8A27B768569E54241F6115875E2973292CF48FF91D45EBED627AE9F0766D22201B20AFDD40E +5B17CF337F2999E0BD15B86E46EB3C18FC12B7DCADCF9DD50C6C7E3F37E615A892DB3F57E250A072 +A49F7277DD6A2C8042698233D35A699B17ECA5DBDA6D250ED4A16FCC893BF0DC2E33FB1EBD7DEDEA +3C1C39603C8B7E1A5A833A8FCDD5570BD088749BB232615366687962C7E56ED089CD7B092505CAFA +5A80F503C4CF337F07ADF0D106937E25670839D491F7BFF7A523DB609D126328C16113ECBCBF9C40 +04904427A108618AE5D4ED809F8CCAF72251104C94EC5BEE21F91B179D31DBA79CEEE5EC7FF698EB +84AB1D2D1A624F58B3622A78844CE51498B2CEF38EAFE259D22C7BA61104651A862008BC1DDDA58C +C45F663EB26428DAA85E7785363A69D2790996EF5D9621D53042F42F794962FEA46E46F37B8AD1FB +76FC8D5CF2146843F8CC625139C75FB42DDA71A752BAC48F294E4C0C8289FC46DA5EFD9C91BDA6D0 +27518B7E81E8B21F755A9615627D5812ACA674D1527A1185EED4E3C628196E7D0759B1CAE6B9B7E9 +01E9599A65230F1EE469CD33B9BD9C104C44E3C1AB966C9678BD0AD78111A4E0F2D07A01A038CEDE +7036D0534D684A1562A17AD64A00F279200C0371B1CBA61747671D2A21D3F9646CA290F6B82418A9 +6FA177C6278277504B7FBA936325F5FA124AB018A15DC18D2C5E8F93CDEEA52BEEDB78A57828D81A +3E6C38B9FAF3DC4EB7273ECE3EA4482A1C6242A335862C2C3717F9C9ED95F77B140C4E1569B2192F +C7DCF702D0BC9A50428EC406F8BD0CAF886B4D979320D3E429816D88F7C7146D960AC12E70F2CB7A +9F4E3E366665AB3F1B4B6440F55EEA26DC9EE0096BB7763731740A537766490C8C174723BF0EB40C +53701AAD12B21D436ADCE22203C1053A9DC4E9F17AE617888C4B4E6F3A720E4E6366BA628221A387 +D8AB15E04AD69387C310D3528BD2FAA5B22BFF3FA494F5FBFAC4F771C9C7402B95580C5AC4BB3AF6 +92A70CB2C851FA5CF1173EEC3EC29B5A05A0B728BBBB51D3B7AD8B0AF17A1563E82FAFD93F8B7118 +1FB7AFE352874F4EC6D334AB6747519AB8E847B7BCED33EB5458A828E074E74BA621BDCD03FEA604 +7F7B6ABDA01FC7514BA1AFF0D4D0C0CB8F4E42D5A87E395D9ACDD02CCC220C157153422018725846 +009A3ACD8C8CDDB66BC6836B4026FD9F526AA275D06C813179E5924F26A25094E7BDA8BD26AFC4CE +B41D8964D4FC4AF1DFB0595BC5D6714C32F15DC7194E9A3A73013C45D8FA55CC0550A12D9AAE8E9F +F199FA28EFC2426D8D1DEFB93A65717AF3EA8E2D5B4AA8EF0EF38E9600F7D4E7D9F1D67A2E63ECE4 +789FA74B159BFE2F91C19B0378BA52E93DF12830D99553B6618645E26126842AB70262D96E35E5E7 +50ECA0CE3458B3E51BEE2F21191136DFDBCA39BDC07939E521E4F492F392DEBD029C1EA237BD89AF +76BC89F618D530160AB16269FA6B693CF14BDC4EC7C630025703C5337F61458FA09104EB15C7CB20 +AA4C9BDB7CEF3A09F25BC7F3149951A7CD75372993B80CD2112F7674CEFD6AFA764AA3486730D2C1 +897A264D82A91709FEC4A21E30D812F558451804EE6F3DEE2C4C437846BCBDA07C5B6CBA1D94AF02 +9163B7383CAC6E088AB1DC14ED3743EE77E26EA7AD3119A76C0B5F925C4DE305CD7BB3A09A453947 +5B9BD79BE28FC462D8718CE05F9D94CAF3387BA55E6E447BF81A9EDDD3A34E17BE66BC52B0C0BB6F +86F6F008829173816D205182ED2ECED319864A796AB65D4E3950288BADA94FA32B6F453AFDFC6C39 +A4FCFE60353A64627E2057D4B379D3240012B3BB0ED0C7876CB83C1BA5EFB6E2A03F340C2B576731 +F848F762A7E1CCAF267EE06D621BC33FC245D0E1547ADC12CC0EB58B26BABDB8EAE9CBFBAB93836F +FF22BDA1831DD01B7346AD377AA298D84628BF1C07433284B0A90FC89F5AEB2651BA2CEA405D4F52 +DDC0E74B871D43F71EB4ACE0D2B401F9348EAC3A2EF0AD295036BF6CF6F870D58E00B619D50EA7DD +77BC28DEF91D805CD527DCBCFDC16C042BF9B874E3B1567EBA4C1E70744B9E7E5BD1FDA6A5FF6E10 +1613FBE58DC46CFAC1A65ADAF65E49757E9304E2AC9A91E0588600C709A61D4231730073A36D473F +518A145E141D0A5A494441B9EA99AC23F60F54F8127B477E1CE698BB4129B4B1DFEEDF10D9E665C2 +47A62F112F5CA30B0AE5DBF3E495FF06EB28EB438CE8AAAD84D5F50FB56A3AF002C23BCF66ABC270 +7AC233FC0F2723DB99D2CFE7D3B3667732A531F5DC315CE74EDB9050BF75D29E6430F57CB6778B2A +CBD57DFCEF896E6766C8FC5C9F9FBD701CD62CACF33EE0FC95E78DADD205B5F42CC63024624BAA0A +B4DD447832B4E1DBA77BDFADD223989F8E958C8D759AAA37930664C6EFEC708116248A2A7AF3D656 +DDEAFD009B7F5333854608E67E5E588A857167ADF9225CF6C641F5E19C3E08678A281199EDDAC831 +B57223B1BEEADFDCBC8F6F25D32FCA2336C808162E8F381656E847FB6CB13969572425AA05AC830C +33DE6E030F86A3A85D2A66A77F103C7042C97205526DC882EA9A00EB8BD5519847EB424C15F808A9 +1652A6CC89B66A5731126DEBADE123C63D88A2E550FACDEB3886FF98646000C64B3A91078012CA30 +904B71737CEF6BECABD43DD702880538F5A70085E6CC6015D2163681067C3D513A8C66032C34A0FE +17A58AD4BC97CA69BF41F11D5E910FDFE9729652D3EA21F8DD8CC19160A8FC77573B1E9CEF4E790A +79D8AD6723B6804E9616466C935303E063DEE29CAA6C3BAEBF278B818C2EC2F13ED645AB452397BF +00DB8B26E115026E256746CD0C78A959364FDE6DEDDCD0F441A61A1EBA32C7BC172BB09512148D1E +BAC9E791B7D51B71CAD2DC9B83B2F99B3726607D9CBE58B499A13753CE87FCDCE21C0AD0528ED0EF +B9B2C927F57C78C626248AA2B835A0791244C5896686A66173EC9F802C4C633A42B086334D2A4878 +0E53D00809247BE64E529F96AD2F8B3922A6097D414DDE1EC76F9552F9B8D58B8E34F359AD792B2B +E50C26DB05035E7497162E7C49C38D3CD9B98D620AA67492BE5AFCA3A81A7080185C7F0B5105223F +1FA77805502A2E8C5FEEA27699858D84A95842C5F2FB68686D59FE24091FCDDE139B6463BC6C7B1E +0E90D20A83651AF00C85797BB9F53ECEC1675C7EE636D0D9E77DBD8F89670F855EE4D4800FF3F695 +0EFF09BBF8A0DAF6B8242840CFA5BA73BEB95115F4A78BCC02D85ECCE0C0F2EF6F328AD1DD6CC049 +5A3315B414A4D61DA50DA46D7ACCEFF6EE56451805D26B0359AF193531F95F6589CEAD6FA041AF15 +3067F88A0A2FECD135C56682DB2B45A71D1FA737C064EE9A4F404BB72A70B3AF0330359393247EC7 +81512482579865240A23CD8479F21C2C44A119EBC4E81B308DD8AA86E60C3DD8ADA50E0DFE8308EB +1A7F201EDE8DCFDA405AEFB47E0E6CA7DDB376DCB21D37F7ACC4D3E9F26B03A8DE0E8940CA3A9E75 +963A389DF8038D2C486072F61C0CEAF500753C7A6352B1CD0338D9212B42A4D3DA23D5BDF44C27C9 +4B88A415A3242FFE2E1B332477A21D2B9CE075EE479C6E657A4D8874A8C53964229310E01ED4F3C6 +86FEF5258EDF3B464DD6FFD7F1CAF473BBE722D60FB14AB4918E93878A8AE4773930B8CEE110F476 +7F42A52D9304C55BE12846C911A10AB9B2E036BF9DFD597F5348D42233315FA80D0F563C388BC253 +2103F05E90DBF1923F229F980A2F4585C7A373511372D07DCBACA583099EA972C03E5AA67E663882 +6DB134564DB993CEEB6E7A6659C7C5C05C310267D5F8A24EEC2D5CC3E3F3C808E6D6068D1A57646B +37FABD98ECB7BAF99E7D9AC4414A491A73CA34C52F394352F6B5A15F0FC4D88622DAC694699C2464 +84ADAC3B1D366AFEDE2A2CD2042C90516A666A19A91C80248B11224BEDDF1A320E230739E755D098 +B6A67315535F4C187CFA67ED817A035056353FC859BF286317996FFFB478A2248B908FF12ABDE705 +402224A3EE5F463DD3D243875C84E02DB968ECA1CC52C75171EA50D6A88CA91327A7AA5795019F36 +C0A19C093A1C9D3723C7568F9D41F2E4FFB712FD47F897703D7A620B586B81936C84AAED61D84332 +B3BEBC4F95B796B93EF7A1F565C494F8A65EDB21E2EE18DC025522EF8E599887CA2836069CDDD889 +88E5862977B7472584303198CCE97EF9F9E1446D1F1F5ED1CFC666A8A0C3A03E1792EFB60A9B4065 +49E0DEDF6ACCDBD98742568B4735A747D8E5DE21E630125AE0C691D054E42199C15B1F80CAFA6E7B +B2005F374A9A5F9900ABB7409CCD50C3AFCCAB1214E6A856F7C7EBA89BC3291801E1343DA9DAD2C6 +ED075C8ECA1423B43E587AEC67E6145272814B3F191B3C285639F9E2D6E148A02DC2CBC0E054D629 +5CD05DBAC1950400A9189316F0265B86A732D302C5BEE8ED233768F237C62600CBAAFF3A110D5EFB +6CC7CA3B92D965CA7C5E8D3E64ECF239FE2507FC797FDBE54C1112B28D4DA44C60AB09D994C5BA78 +D663A2591934CC052BC70CD1DCA3325C66C9CB982E2039F5DB70C848D3DCEF655B1C2CD0CEC8865F +E8E1C0A267BE4F707ECE6F5A3DFCA3CC1EDF92C760439F51AA69A4C1801E96CA4D6EA4AD980258F3 +D15C893913ABCE09101984C61B91D603053E49A97CB82FBA707DAE8AF1D579FD69C8481CB7B712CB +CDDB4D287BE995E32C02B399602A08B9DD849039B5673F1930BEC7BF366EB082D2CA5DB2385C8CC4 +5BE3FC0E31820191A814EBA7C4F23B1938E6C4D800732787CD2CB97F762DFC85D4B798809B5F2254 +D826CA42B32695428D120298B44CF38494E56240B75DF1E41E46E53C44DC505452256DFEC819408D +605FF14D6C1F3F152F2FEA96EA0AB3B472D8704E06BE9F8C3E8395CAADD06D6DA033E81ADE5DC3B8 +3DAFF743C6E9E48716003D358DF63CD7FD3E2F727D1F2D0C29962F76D5C95ED44B6F08D052025A66 +5785F264A3D5F5593677B630E628B5EA81FB37CFFD7A30B7FAD226B6FDC82B0878AF4C0EC4F4243A +807B9839EA62BCBDF7C2E9B30A623876E632E084EBF4A21EDA04FC88A1C07021D0C72EC3E969D449 +FEB08E5826EC20E55B21EA71EA59F6E3B0710B0DDAB3261B4A2029ECAB68C19ADD5174E55D5E984A +4E5F38F592A302FEE6ECE732DDE841A28672C620CC5D687455A5C06FA9FE688394A04F96312ED025 +B7AA6FBCE2925F3AE559CC1886BEECDB70822E2E5CA3F732A87404B1536AAC469989E9610CFA440A +CE43875A70CA51F36CB6F629D9424C1E35A88F92D5DA3CD8CBAE6E8425A36968E21F4F30349749E0 +205BFF8D552837D6FC39532525370BBAC833F75F1854C93FC533A4AA53ADF7008173A70D94A4EBF5 +38EA9E62BCDA7C20E0A073BEE2EFAC34D2EF1D03BABD5147659E50B557045B2EB89DB303749B04D3 +F54B43FED612FCC68206E001A7AFE90230D9C12F74A32C7EDB5D0241DC3A5D51481FD7C8FAE08FEE +263FBCED7C7D911B3A303C835AF5FADFD218F61A9D6DE80485ABCA88200047B094441F7767B97A24 +E8C612590FA2407BAB1E8B56C71914EEF2355DD97CFAFCC192BC06FCE063D3D9D1A629AADC75E3BF +207234C208E7E30663EDD691043065C9CBC473D97C6D4DD3DFF59D6A9ABCDD4412C3128F603160AA +D8F81C6E7A4DCAF35F3A99B4EA10A34375B477C2BF846521A7EABD4D28078E9340452A198F3F5ACC +3DB7E3908939FF6E3709C6A3FD9889439A4AE3E10B618CC92E14B68429A3AD2C80940A1079452EC2 +66F254657BE7D79A2A24084AF73F6DF71FBCD32BF6913A3FAB25F977787F7BB0C3A3E8BAB38D7A2D +B0B4826950643DD1E03BD7DD1FB149A33862A89226B7CB454DAF613128C2075470E42E70A9444A8E +6ECA526345AB48E6F5160BA23B5BDDFDA6049EC44ED1461C7E0DD514B16E2FB285F72039DE3C7982 +EFD40D7F6C8E8F4CF35AC71B467BFC578002E8D2239A2FD2C4BCCDD8AF3D7DB1F4AE7F2D2E0811DF +9D0155BA6EDE50B5F052F14F6AB884FFF244D8806C07EBCB49ED22D85DF696995991A954AA97A1EC +D86ACD76E061B7541E87997FEF0657A826BD88EF3A4A5920462C6595E7A156F453291CA044CED810 +860C3B0149BCE73BECA713040664AD0591304106129600AF71317B0D2907839CEAC99515D357E980 +B1937B6E1200AACADA205421001F1B2F91753E80D2263C56AA164A74701A8D5FD28E46480B0DD963 +A683A1F355D7FB4463C7347C94EA5E2CA40B60B56297CB22D972C5BB10E56715A955605256C1541D +9F3BC5768A6F355CD3B863F0FA1A781EDB49368F51B29481CBB41D4AEB07AF9DBE8F52C5D0FF75F7 +FB6431D37D6AED84D78C778871CB0F715B4F07580F23B586C969C81B471FF6A6C7276F7E141E02A8 +584D4B9AB00E7BD643D2C3FAAA299B1F1E25048461952EA42D4882768A70DE46B213A287F8D31AC4 +6D5436F22A796C05D1FE50A9BC2A928066627A0D87DD57A3AD91DB446404B41557D1457873482005 +EA20916BBE46C613F456C849D46BA79D20627B446B2F49E3FA309AE14F8C420CFD94922CBC0FB9D3 +5A0F7DBEF577F1849A1A80E0011DA8AC082A8C6F61658E65AD177ABDF23EE17C8CF0D26B9FA3A6E9 +4837EB9E930336889767A8D7EA3CE980A8EA95528B004957BE6067CD9BD8E02A0F23CC1762CCA656 +D33412FF45E917FD4A03EB6E8C1F43FDB0A8965A33B4FD26BC24A20B304CA817E88495BA9B361A3E +933717FFB0271F7F70C5D3CBA1E86D0F51BF3ABA194DAF32C35C796627D00C7B2271ACE2463E37E9 +7B3C826CF3DB60028F240F9452CBE08F7EBCC5FDB1BCBB3C327A9F450B9E5671916101D6E3E5E458 +CA31F04D12F592F83BADA2C3683D3886AA3B403963AB5DBE220FEC00037A745839F67A3635DFD3BF +F08F367482962DED88ECF6322852D643A54D5D303EB04BFDDEE9BBA1EBCCBA7C653B3A613A8E719A +DEBE3CE1BD7E754E5F4977E863E3C2D388A65227B451D4F3A4F94E06513CBA4AC1F2F511613FF035 +611684CCC461599000E546E4D972CA6960E095A526E4735A23421A4C9B597ECE08AFA2753592BD16 +DED93255A1E33DEECE3C5EB77B94670E8137F2A4A4B98AC193258E7DEA5DB8408A806188F2D1DDC4 +40CCF0E9A6E2F0C78FDBD7B68DD4939D2458C1965BF8BED4564B32462FFF3EC892C03B11D3EA813F +AB4CFBE8D3016329C5B7E3DFED0F08284D44AA0B7A2F6BC96EA4503E8EF52A64C22BED6B452581AE +8FF8917D53976471941A9116A2D878FB2541B561767ABD4E31CCD8A590CA03494C62AFFD64EA0A1B +C779173DAD84999C7A8D844EB1259DE7BB5B25CD023537A474A524EBE4660B22568949E624D8FEA0 +AD37F4CE1EC75955EEFA49C6BF1803BE87E9C9865FF3F6B8525B8C15FE8835CA153D27E6C0FF0CA5 +1029A7A9185D25F0F14D86FC797DCC1F99EE97E2054B9C2A2E06FDBEB8DEF6CDD368BF23A858D9F8 +C1DEFDCEAF1B4A8DE5EAFC604CECCF0D285BE00AA912EAB66EFF4D37AD2EFE34853BBFD87CE09B18 +749B489943EECAE7887B006FB827D10191DAD18466CD1F86505879310A8B171F902EA0C26A388E13 +B53C700272CEE2BFB47ACB58247C13449C6BB9D01232C32517358F1A3DE064D43C18F8827D53789C +CF3CE2EBE78949A6ABFA1A6B8414CE360A5E22AFB7D1DCE6F5A06182C3B984B4F9BB1A905A9D5A14 +83750A1DE0A857CD5C06945EB7D4A2A6BF1237F32A154FDC06D51A703D44FE052FD3C53E9E8F417B +35D1C851F9203A8997521529F21AD8498F96930AA77EBAF82EE02A57BC77C792D9F220294B45F48E +A8FD94E01CD25645D36D168923562F3FDC93CB79DD4760DA0C103C2675722D7A1B79FCB4245ED12F +A0DB52492C9CCE58B333CFEE822812F7DCA68E802C451B5CFAEBAC608B950386B6C58239D1C62D62 +4DD5D15782FC552222CCA06DDF387B373E32C3C2864C63C768350C37283760F3515A5B0AFD66C48A +B522EB3E808C061F5CD6BD96CD18C9839D30508E7D4EDB88E8F11E31E10919B16B7971F06D7877A0 +58D8A4944C84FC6CAEDF3341B48B6E0D3C7B85D710E0C35F5B5053CF4B4798B3778CC28B2DC7AE0D +F3A49F9F3BCD8E95D746C35C3F47D68B8AA35D97AA08E711B5FBE70D1A623C82541EBDC51A827D0A +69E6C049087AD26F256EB7577F58CCFFBCCBA5A95D093DC29464C9A38DE95BC6B1853963B2DEB0B5 +7AD1248D6F1625E115EEB9510B5772AAE4E3C866657DB0B3BF0E0AC345E116F8D4976B770876FFE3 +748C36165522991F46A36F193DD1A1C94713673C7E4C81582391B636C72DE94CE6254374F99B623E +5686C13D8A8322E83E11BB0B0A896C6A8C2C4F756C5385CD7017F26D23F7C3EE97372C868C8C9155 +81723BB6B76B4C3CE8998E4FA6CA40B633DFDAA59BA902A4952DA90EC4FC3CF0F2676ACFA7F76F78 +236FA2DE10FD3545357215246BB7E527F277C28B353CC6D79DCEF21BCC8F77603CDD58A2CCDDBE3A +9802F941CED8E035313875319548C41992A2BE939A17CC109426E33825AE59BCD17CB19F50D972FF +CBE7D9B4B0BB095303D9DC9D406696C2508D6CE99E11CF00F6461147E97449ED5F486D480A86D3A7 +ACECB7E9A945984724EFC21C5079B1FD03ED803C2DEAFCE3327D2D7827715FD65D9506216C88B0FA +26935E95C64114A51919D419038B1A7E9C1E829FBFB53275093752DF19891A97F3CBF7719C1FD6CB +17019A6D2D25360ECA804C4B35172662CC4769D2B785C6C87E5A4ECCE31704E59F71263B7C3CAEC8 +ACB4C7426EC25F11A0042323EE6C3EEB04284DBAE2C770BC419DCE79BD4560AEA41571C3B595F525 +60191DC7A8FBF63D413A77A0905E517441B16C2B501EA2F9E99CC38D052679F288FDF1894542E3A6 +6989A0090185EB2E75134BFA3D9147C3DB8A621D9D35E37786853779E157B47F71626D6B3E633005 +9159C17596C1B87FE2B4FF47ED9D78FA4C2160077276C8B58CEF5DC030B4A5D83CF257096C047FE6 +4DE307C598B815058E72D5F57DF5C369E664E137DE29349E2F9DCD8C9F4EBA6E765B6327D7A20DFC +B20711273FD8091CBA605C4C494248076F7E03DF65A6A50164980BBBB708741E5BF6056E6F996DC0 +7FFF408C5B8EAB8DCEC315E92873228C805D4440A6470E3EE3983758DD211C9CECDBFAA4C9300CBA +00608A4B2404A3C7AF017A3B7E67F39F0B51ACF950D3E75CC7BC2B8D3480202FA958E8EE0B240501 +5232EE0D264C7CA02C18CA45CB3C2DE322D3EB7F00F9455DB6C5B1F4E59C3E95520EC36D7D903CBB +625D70B54BF6F8255E412604BBB29FEE026CC660577F91DB1DB4A613EEEFB20CF7AE3CD89D565AC8 +38416B01B5DE4FFA5550D17FB51FBBEBE21CF1D56038863EE931B90DEC2E211ED42BA92EC244D4CE +2C4EC5CA87A026992772DC2AF754FC982B94F36EA7B7BF75E0ECE90CBB2A6AA1A012E8898BD679C2 +3CB3827C35D5D02F0569C7AA82615D4AA67518ECF668D3B57D6EF1A8013424AC2268BA0D9A74D588 +79EDCF6382A89D397864940303EAEC45A38304BA8B1CB198967AE23EB81054BE74B16909A405E8A7 +799CEE3C270FE2A6DC50BD7370B6B2C8FDB9A87D88D5D40348D3984E39C693B6F4486D994778607A +80A3122872DD65E40492107C71C3CF708A9717E9EEFAFBDDC239C53AA9645B711038E59C8B861B37 +411AB2039BEDF9CFD00F08D9C5D76154427FF5DD39878CECC5D7BFB3F1F035087185C0981F3C2139 +BE84872FFAD3408531C4EA9387B89F5E3EC779E8850D50992DFDCF9132BC551E985943B07618AC10 +D1150451F0844C0DC41D6E17EB508DC8689EC726400D5A7F6FEB3CC7BCE05F09228B7CB2C5393664 +D8DD9A4B96B1020EF25D70AA2D91CAE93AFB5F2BF0AA18CA5C599FA1A708EF35BF8F7FFEC9AFC1F2 +42870D028B2B1459063B493943EF1283829783E1010242E5CF4DA39D93D506F3892936E7D6CF1124 +70A521D397438733D053944CFF12D6FFAE8246F20618684F263715AA98E15D72A526383E05C23214 +B78338E5B476F0981D90056E6E5D0DB66B1DF2298E597B2ABE1D817E18BEB056E65EDB4234342D96 +00470B1420C9210419D834E431B82F58608C87AC361A02D0F1FE4B470A3D71E0D21BB87E1023D428 +E23D596CB9E1A2184403A16E36E644BCCF9BBDE27290485057E62827283E7380AF786BF395B3961B +A5EA469C315763FA59E0F176EF81985F38B882DE56A74D128E256D1B89939728E55A92ABA21A6B78 +44FAC1BA7BBDD8B34A18194A2984B000380FE9F672E83EFDBF276FE797A325815B0F25CC95C97A9D +ACF56D583486305D7C9E51A7E337D14E3B900333EB38FD93A99587DA2341B10C059C71CE080FE753 +3C0F059FA40E560AF9C4A41A4BE6FB45846FF8F78165E10B4AD40F264BCF5596A1E8EF8CB6EA4B1A +3A5C69059AB1563843679ECB2511A90E8898F54295649CB73D277760D8D04ABACC7BCC6E777A0530 +E2067CCBC08673F9C8C178F9D672AC8A15E5367F0C5651B53E75E0CFA57C931746AE1A679C246D7C +9417F1CD89DDDBD1173C2F880B7B3847CBCCEBF99F7122E832D7C9BAFE2B54CBAA1ED48158DE3F36 +238B76B0E67644A28AEA996DDC006F6AC0242E4B667639E7523CBC90A0561193C1AF34481C2EF402 +EE43A82E1EBF4E3D601BB36B2D95CD93550D61CEE7A94E72F6D30C32C8F91A61E964B1F66ACFC398 +7F95D4028F116E9A9A8474AA29C1C1A984BE0E393BDC41DCEF6A6F1018DB60D52024899D8EB5D55D +324D73F39BFA47377B9E15B3B06A7585589FCF52A54684173E5183367E7B0952DC4BC2767C4C6247 +B1D6103E52BC7B7EA6298F454C5D97AC575F19C10ACDFF4E10C7D3755CFAB4200CAC545269FF1D8D +B0D607C7AD47F40DDF257AB4E7D0750577003C13E4941960C3DD7B0774DDAC18E8ABAF8F53E03CBE +F6D57B44F24CF821014C064278FD51B3427593D17694B4ABCE81F49CBB984C5878CDF0C38D1ED7FD +99B0B9A3BD8D8FF6219588B3B8FA59D0CDD1D9B2F65122AB45E48F1757467B9204926140E3C350C5 +A927A2E700173053EC35D3F1DA2D7258714C97FAA857F0898917BD94625C6D1E2D77138EFCAAAF51 +7B17FE187A2212C24A881A2C6A647DEF6376ED80AE4175C5EE80921F001995B44E49F0D33DD9075A +CF33BB03671C0BCC34AD5784AD1CDFED3A6D9BA103B3DDC1CC2DE74DBB576A0277715275218CD19C +A8899209125266D8BF1286F881DCC2C383749D1E768D670F4099F7DE959EDFE852583183C9111601 +2881A56A24AAF020EA45CD5F39660DEBCE30AC1C7B8CFC60387B1B0C3E361BE612FDFA9F01B7E4B4 +A18839A2C7E0E393EBC5AD9A8A4EBC316A740C1C295D9EF5F4DFFA0667F9582C0BB837B142C4CFC6 +B1798E9476D0631111033B8BA75A10FDC800E2AB1E0E829632F869CFE4737BE9E2800759EE0831DC +7D1195EAF80555771981DD6DC6606812D92CB8EF86447F5F6C6F626D0E265C67E52A6319189EE349 +D48E49DFE6A9E98F76C414A1E3217AE0A215A17E54AA498F4ECDC50242ACC7E2322F63BB2FF2189D +057E7354E32A3ED1803116176B9B9D0129930F919E2FEC280B2C8924E49E7BB75768A2EE1DA8ADBE +D4E3589906DF1B923AEF84C1BD327438B731012E69BB0D43A1842CB88BB54EA4516477F704CFEB28 +6E3EA483445AD4D74586FCF32E96D366901084365F693A53C5FB532FBFE7BC0CADC404C4985042D6 +8DBB90A6DCDA3531EE324D558A214F935CD9FCC9A0CEBE9B5FB0323F4B3820529599EF48EE068B5A +CE85004FEA2984F0A86F5AC9D56163BBFE1142B774148F1EB0A4DC89C3349052533A7DE66729DB24 +41B82F8F7360111DACF69293C9B281A0534F3E9E9224A75C49A832F28B2E497262475507B6DDFA9F +01CA0A6696E3F5AC7EA68595EBA0C2EB8A47813FF936D84AC1B23ECA7AA2862B793CCBB0DF9FDD49 +31BEF354CEC12FBF478559FEC29F81ADF4452E83963E56541D31F3691C93A50F0BBA5E9552C4F2A2 +3A6E53060729854A3DD71CC4308B91957DB19E66AAA18FA67055A950F1C2CFF78A03BC1A588CF624 +696068068719AFB1001C4581EE072113882D9052B21E355D401ED8CD24D067B99E616BDA5A0A5A93 +36FC499632B79FF2FD0DEFB096EF46B75E2D4E0F48DAEA239719FEC4D9A29818F5875FC5041A9EDB +D26CAF0ACE14CC80BA49BBA59E918EB3D8F1E541AA16026585A2F72DF7D83541816DE46981FB3EFD +0C30E458CFAD04C79421AB7C4925E23AEA07F9F018431C790002596D26BD9663B51B699DF53E4882 +CBC34EDE88EB55045B889B6062E35FD1E018BCE785157B85EC3B9CA6C85D4B16238275385B8285DB +012D8FB7C9F5B946A41D7A0FB878FF72C39683144D8A007CFF631B43748F2D5FC690300F9BC0C837 +006B92ECEBE0605E8C3A4A400E18AE8997D1B45FEE10068E247C647CF82C6DFBE5E881D511FFA687 +B7AEB78546BFD07D5F7EC242DCEF4930D8AAAD8C6152B6642AAC325963FD147F236BB850A9966573 +9D06CDBD7CA79A527DCF461E33F22BC9C5DB00DA2BD3DDDD8C99D99793BC98282AA8872FF96C3942 +85D82D9419EB78B6AE37A5F519397700F75D624A09BD255B576E955A323E784E8FC31131F003B0E3 +024A4F58FEF2A6C043796201FC425482E1155E229D1B2D43EF7B0D22322B22EF5C9A1BE026A1C3D3 +75EDAFF99597E1E5477952A4E8D2ACF5D014BC00DC2A272FA62B6983E27D228881E2EF2B8B95A681 +CBE90C5FDE16331C85222FE2A16F0A3C3000A63E2E21666C0C119F8AF89A543D37977069A5ACF155 +6324F05204CE8CAD50FF4FB630D9CBBFC324DEDA584AA56A99D3A76FF55BDC2C2EA3A021361CCD4A +83C7A5E2768D210FA6DE889FD48A39D679C94EC3C99A8D33FF11377DA7F6F1B71A2A05B302ECDE95 +4F26773F39AC881542F0D0969C3995C3519A8EF70B4220D86BF01BEECC6462855E7B686E1AFF1CA9 +1FB8FD8B4A69E10EE0C2AD94ADD44449506F9B6EF43641F2026EFF6E605C670560C2B74706FB949A +A7E8CC6A2D0D6207E457E7FD87EC1B9092DC68B9143947CC8ED14AFDDCBF8FDDA228A76847F96802 +E561F67CEEFDE45AE587673983FC04C96744DBAA83F2DC838D633943C75DCB9E6410474EB27B348F +26E505F0AB90878940E846C5E9F3C5FE8C3558C3236B1B88C405716949B8506841CABE1717474BB7 +C30DB91CDEE33B0F844811762FAEC535BDCF84C1C747CEF9B1FA61D2AFB5A81335BC42C06A94D7D5 +9B7EDE55BCF6F9867AEE107555CDD084B7684C2C87087475A39A9DA6347BE281CE5635A4D07865BA +98CE26C1465B1AB0343F49FF37B4D0CA9F3BB693D78DC3B21925CB996A038DCC172527FE57C07460 +EF39C07D4396E7FA970D9F22ABD21A9C794B64AD96762C7428F59A8757C36D6C4FFB23216195A04C +2A2C2E7B10EF7193931544D782FEE4B91E01119C5553BBC6252270A8D8C56DD62D448F5AD8DC69CC +B45E1F17F0AA1E445129DD00F000005B23D38DE93A3BE55A4C041947F36B4E4536E307D0180553F9 +2E46B743881CB5D5386C48C7D5F84C2BCD06B9C501F78C7EE61FA23516791FCF4DB278AF688A2E60 +10A56692AD92008497487EDFE4BD5FA083FA544138B20D6940020887E35D46E093B71F7A04A67460 +DC8116B4D4839625D7CA6959D6831CD93F81AC4EA2709036DD738364FDE71113BF22EBF13DFE1642 +E564701E6F0FFE7511EDF03FE448C2B28C64FB7D54B94CA576E481FA56B2B18AF10C71F699B6BFD4 +7459CDE1869D0FD306BF489A6F42E5B2F05CCF55BB6B9526973D19CB134CA7F13F1DB3716F8CC217 +73A832568C16250B5CDB16DF24BF81D49F5B37018BD310262EA7078107868AB0216CEC83CEFCAB1E +9F2C665A31585CA04DC01879CAA79AAA5AB201B516F7052B01B16BEE5606098393B0E5D9F9E5E3F4 +EB20F63C958E796DF41CF28839F5C62A0431648745D7837B519F3AA36BC6C08EF040CCF53D9B6D8C +0C7D1A84D707EC57A3C6AC9A62AB37251A01A5ED40FDEC6F5BE6E34C6A91D058319439778A2EE5D0 +363E2E1F33463C33327D05FFC0CBF08D5BC457C7230448972FB9B4D0D782BA7DBF10D3FFEF8BF523 +6EC16D4DD6D0D870D9D5EB5C64C9A46A4F583D4F831FEE74B0E5B33A09ABFD4444929BD8F638CD72 +EAB99CF2E9551DF427683964A592E49D186F285258C5D5F62196A98532421D73E3495F82695FEEC6 +E1952C562D546B28618FFAEEBEFF03A57F4D855021F85B0C7BC37FCC6DA9AECA099B646B99D41896 +09D3FF2D56422F8C37E97640293EC7C90E3380887836F4938FBF495CAC14FBA5648D89282D8D49D9 +1AF73ED36581139D8BD42551E263E830EA3C6EB381D85C42D74C50DB0CCAEC03F535ADE92128A016 +0E811C34748309AF7604919B66CD43EB5CA975302DCB6076FEB6BDD6FF55976FE990FB0CE9ABB11B +195403FB26E3D6C6A0DE1C5BE79E171A61E21F79EE8DBE7A832519813EF6B33EA098C2C32ADEA219 +AB2AAC8B093F40000995539D1276D5F2EF84CCD099B71FE4269BDBDB6A8D59C86F7D2E3FBCCF8773 +D0FAE97640BC1AD43CB4B992BFADFB09DBD0CAAEB8CD9DA264187C4F97300E9A6C9DEED5525479E6 +05C65AE336CBBDF4E5D7F79AD098F977285E065579B748FEAA97F2A753E1F962FCAB68D72BAA8EE4 +FF6691C23E31BC0F3E981A96FB440404856AE1AB32A7205B17D411D8F21C8C93B704D07EC594422A +BC368CDA2B1610CE6A973F4474E12B78B532666797F5755D269772C9F5400B3BFC6C58395D38527E +2CCCF29B56123F7DCEF3BDE5DC1DFC5B0293BB125085B1D2D929BC3EE84F4FAD571A4991C3DEE03F +2DB3A3097E52B1A7D5C73CCB6148EAC62E8E36DE9A71C57638C6E4D5D9DED18174E8C390E50B4A5B +913C074EEAEBE390B214B3A68F02862B9A296DB4B409769649E51D738CBBDFB7702E15C73C2AFC6B +C37CE15171F4E822CF20EFE55D9F061AA43E648989628FF79E65932390CBB15D8E621333B18B11C3 +BDF96F841D7434E01AD501FEA964A75B248A35CD9DF9A37E48A1E5A09C624B93CE44F0042FA00D7F +9EE89B9F7AB785E9C718CF6E7228F743271C2C9BBA17E5208B920E44E765D99D86650EB454B0FAAA +112753AA1BD3A24239E9C5FC47EEB1547AC9D23731B8DC48B9707830DAEC60C8D3790BBA1120F776 +4EFAC542CFFBCD5C05F9510B27B2534B704ECD36C8B041FD49A96881302FFF5B0163A2DD09C751D6 +D6AFEA9170A4F4C4AB8D46E62F763FE1BDA51DD1CE4A27E772F3A2869155F762FF26B7AA6FCFA4F1 +292E56F03AAB6322BF867E7710C34D43B5D85B45AA68014AD7879EED051B1933E491496E3E26D9AA +8B80A07BF2B94F1077E84A9726F08199887D66DE7A307BF33C30DD9CF3DA188088C03B2BAD09A217 +6B110DB2C868B53DA9A66C85737BA66C93C58A259860E294AD0191E3A72C73F40B0BD98699AA08DA +F03587B78F391F3A4313C58D9F29B53C70785637BD0C58310109C54091AB0A34CBB0C478613A7AC0 +FB8F0A8B4645AC966395D8BA775262CD291136AFFDDF01C1D83DD4EB3B59CCAD18057FE7D92A8CD4 +A58F22508D9FD7CF356571F701BBB23E749BDDCBF8A317FDA0AEFD952BB18545610FFAD3AC143D35 +1B8DB3F66293375E0E50235F0D0466932181D377EDD32A5F0FFA4E22B5A0CB4F343D9A7E4A342E9D +09DFF6C697630CD3971802C277A5590B8CA94BDE6B38446C794D072BBCCB724D5BC208EEF1B018D7 +39373BB910D668882CAA779C2D686081DE6A2606417B54D7C20E0E7F722648D893E4EDBAE8F00D6A +6DA3712F91AE860C756D1127D133AB828E9D80023B50B162C5A1C5CDF70CCB3FDD7EA060ED20838B +E1E50C4094C9E79E1A0187CDF780CAF45A725964F004253E034C5BE46BBF89D94631F1A33BAA35B8 +4FA2A9D08481C6674126CD96ED05DCE48BDA069D902D6836D5DFBA701DC0F98A863E64F0E312145D +8DC0B77F25B43AEC729A1243B45B08CA228DD6101CAA2AC5ADCC8EFF84A4CA3F254176C2CC711EE6 +C273835D0FD3528ECA2A976B88E51FE347FDB60F32370B66D338931D6581630ED586F349C638960C +31AE4204E89521A96E1219E696B913DEB2AAB7A3B022D06F34FDFCB810A04E60A4FEBE284C2F063E +0AE9EDF87704921CCFA193BDC912B747E13570066223A49F1F6E2AF0D4D65DA04CA876FF7A462FFC +9C0BA2CC545C3BD36DBE762F32B2D6BE5867C59F479195C92440DC165098B74EA5C3AD93CDF2D410 +B04C16BC7801E7956F4E5107450787AA592493171C3628E6B8F49D4F8429EB98DC52EF025F001387 +BC1A7093F7A99F10B5D2D7DD8BBB393BF6E56F08F4F7FA1A343F220D5A1EAE7168C74D41BE1DC1A8 +3BD65B72B982F4F7B34F24F97F9EC9A91011064031FACFF2A14921A32024385F4E061CD07D152E74 +1BF97156D951A342488FA7F5EF934CCAD13E2753A0AB7A1F565C2F7F6B349DF03BBC25BBD972A9AD +F809BB5C5048A8CCEF9297B2ED3324D18867F293CC66E88B3A39D107B610DFE79A3B4E83A96D3D52 +A17FE8A62C9FDD271130148366942C9CE57558D023DA5F7501319EBFA33DE9E6D1E76D7C20DB8A09 +B657839DA99F3D8143F1EE6253A3295C9651FA4366547893C2DC7ABCBF4BB7609DE5D001E0A36D9F +FBE01F7D0903B3208AE8547E2E5F14EC1AF4C2535CA8F4EA37E3F3CE172C7A1E8308995B1CC23E6E +81190246BCAB6E755BF868D449BB02A2AA87C44C9CC0F571ADC72547CEECBE104BB274B8AC16DCB7 +5D5F458D356466B921ACDEEAE384E2EB1DF6EF393B41B9747F0A4FAEB4AF1928D9AD6FB7E06FDC62 +1E4C6FC98CFB43F88584BD55D9B97CC9549093EDE586912161931162B1B1D52D0443260DABA02AF2 +B4432100D5506546013DA703573FA8013685CC798CE501960093DED713FFCCF89CA2B9106390198C +29A00864108CDCC1984A8BAB53919028C01B26ECC7925E38CBE6CCA8978EE21C2B06E7B3E48FBA97 +8E2A7D186E563C088F84AA23178B60E4729EE87D67B1091F3B6973676C1CBFE6530EB773C62E2C24 +97014AB0E8B71A1F4E86A378AA26591511BEE3CF3D64C94848582E1354E1605B6457823F2C5E640A +D3802946BB2E7E8E594E8C04B430C2385DD40746CE8534F50842E74D7115F3DB0C72D1C9C607C657 +3B094AEB73B7A79876CFFC3E2F8C9FEAAA07D3BFCE05B61F7749A8793BE90CCCECA2D7077F25E899 +D3331FE161A7E86C842495D584C6E4A0880B2951D8A13B88C4672080A0B1BE36BF47C3ACE7288CFE +41A8C1BAA6F0814A947FBD6B3AA72B6C73A8C578CA51CCC96F2352316C467BB960E981F2B6485BFB +44B577E71EFDA16E7405954BC7C9F0759F5A9F1EBCD2FA9CC9648D5831A68887F41B15081A204C24 +B4B992A231DEF9E698D4C3A25B6F5474F5BE6A601F2D337A58A0D21FF37FD91EB86D1D738893A03A +69F0CD743F611CDFFE69DB2C6ED0E4611D56F803BB0DC06E7FE85A303839612707647B1BE9FAF8D6 +84122CA9E5CB8BDE2936D3F4FF254D31529D7538BBD4D35539489F9E7316F24214B996BCDCF1818E +749A71CF0E8845AA1E2A58AA62A48E02BA4564625D20AA220EE719608521D7D7A7FCA0BD8904A401 +9819D371F3F59D46C1354E5FC1A6E5F79B20CF4ACA2BF0F2DE73DA193A6F9ACBFE0B4731C4BCEBE6 +D96FE822965DE965232282A3A130361F188B3AABDA95A8A2790D9240BE008B6A6DE4BBFCADA05B67 +86B9BB8E0DFA0C30043A3B07ED46277E07B9808422C8ED16758B9C396F4EA929D769785B2C9568E5 +70A83B989B25CE200F1727D41E2B702E7F88F1784F4C83FA60A74EB26B2DA95126E508ED519A61CC +151DB6804F61826C5F86D8FA89D06E526FED97A0DB88EDB432FF32C1ACC9B622EEDF601081AF7B96 +3C9CFC1D13E4A9C74FEA0A1C8E3D8653CD92A944D4CA6B0D306619AFD503506D77732D6514F604BE +4610C2560931BDE0B40939BC1D126B0E97F72AE1B4A9252123B54F7A27E0CFA4425B4546526FD741 +CA77952B10D13E0AC2E32006A903808FF0CD013F936238C74CC75FD915244C56A8412F37F0134840 +347699508D6F3D7F3203A25B7C70100719582CD588590EE34B3AB13E255B613A6D00386A0104CC5E +D2C646F09A88888D3751651D5646C5227A3C80E8DA1B0A331121DD2429F1F4775D30564DFF47D01B +BE2C6C72CE4D1FD9A2077C04D2B0274B8916F6A9D1A4A6964A534F47CF241D5A8E34B23F85BE9ACF +FC2FEA961F277539F215F8728D6788F67BEAF45502839BCF23D8763C3949352F00C579A9A4FC408E +C625E310DAE61512DFE6844E82D36A2F81709E1F05B38AE9C222ED62C961EE63593CED7AAF73CE2E +D3667740C77B309B93EEFE1B4BA65D48575A66BE86743DC9E5D3C2FF418D11F7F211B86E827EE1DF +C3613E7498030F07050524536D1F8A94DDB6698BE7B963C55CB3F74B676CD815A7B3DF4B1A0EA2BE +1B0B9A11FFBFD5B1FA49668AEE14629316AF436A0821C20BEEF7B3480847934A99F6D85B68F4DDF8 +859A754E009428AF89A90D1852C220A607FF0806E8080726EDC94D691D214B4521C147C4273AEBDD +BB4A697EF16448CD9B2FC95293305858DECFD406B89B9F3FDAE2AC579E80CF321EBAE5701FB2F7CA +D8ED04B4A63115886D45D6120F69AEF1A21D80AD3C2D35D2899F1902242B96CD349E0AAADA40F7A1 +1282B6B52BDD97708E58DC5E2D22D1153E5FA3F3B300BCDFAF98DEC2F4E3C82A1C85F985735F3987 +4F557579F422664E07CBE19DA680EFB0FC82C323EC5C4644C51709AC8D674608A8043C91E6C7988D +430F10BA6CE1FC7FC0604FCD8F723895250AEC36CC35B3FA14FE2A0D24095DCC30B2093F2298F5F0 +A97676A0BE66C3DC9ADACFE2FC0F721A20E945AFC1096A619075D5E9A264C796EC6C90EF1AEEA8DC +089B44FFC13D27CB2370070A52D4416C53F364393E46EDD7EDE00799960CE6E0D57E4909E88ADD64 +BDD2B0EBE2D73FA6ACF8B40280DAA0637E705C65AABD523B8815F22F23E9FF81E7829C7E4BC980C9 +143AEBE1A04DC0D253396BBB7268BD5AEEA356B610D5DCEE03135E00AE34388251F31714A1C40E18 +2652C48CDA2211A22CB6F02490E69A44CECB169754C53B16028D352E0119F5D5FAE0BD7EA1CDA647 +12A6147374B64244E21E9EC9F0D1381AD22D5B6212B26C3F9AA5F6045F25DD9F5EB4489EA39B1945 +331AC70510C5752557DE21D0A6CFC1EB10A98FA867B76DA6E4249469F591FD154D39E89364A43DB0 +07AA0D7A911CFAE6CE2B557997FBC44F55A27F622BD7B8B10EC9F5D10F2649A646FD964AE1B111B3 +5B46A252C4DEE44E7426EB5739F24E8A390694597DB3A1FE7800C97E59558322F0E49A0CCE2AD94B +1E2D1026AFA771723E3F523916F55ED866C9FB4A2F759651C613A2CFF362028CDF9D38F05D4C7C60 +24C533E930B64B099FB1AF04B01F5FB9CA6867E6EFF55A772C5391831059987E10CBF987E3F378E0 +1329F73D54DC0484177D3C3C06F67397955FF1CA4EF8AD1606B70455255D631A7D6EB92BFDBA14A0 +FF28B2ACE7E81AD666EA9B3A0F5A6BA3B5DFE35044FA4B3D8ED956009C60E98CC132F2E84967F4A9 +8A67B336D5EE7CAF7DD1F74D1FA08619941361FA7312CF225D89CEF97E864C8369EAFAB94D97F056 +5505D825972B754F6729596EEA91210B75DD8F645382ACE36DE60819A02B3B48DD00F5485F9264F9 +FA926D732E2C267B0BE8CA98526F124F97EFDB86132C5EF16B103908172FC51F286FFE45FF253512 +E0033F037FF182BA536A9EB2DF2D1DB257D9C86C46E1B002FB32AC70CA9462E6EB48994752CEBCE3 +9F08ABD4F4B0889283E55500702185A841E328 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndResource +/Times-Roman-iso1252 /Times-Roman ISO1252Encoding psp_definefont +/Times-Italic-iso1252 /Times-Italic ISO1252Encoding psp_definefont +/NimbusMonL-Regu-iso1252 /NimbusMonL-Regu ISO1252Encoding psp_definefont +295 271 moveto +0 0 0 setrgbcolor +/Symbol findfont 50 -50 matrix scale makefont setfont + +show +370 271 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<4D6F64696669636174696F6E> +show +653 271 moveto +<6475> +show +725 271 moveto +<66696368696572> +show +877 271 moveto +1 0 0 setrgbcolor +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<534D4553485F535243> +show +1149 271 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<2F> +show +1162 271 moveto +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<737263> +show +1223 271 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<2F> +show +1236 271 moveto +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<534D4553485F49> +show +1435 271 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<2F> +show +1448 271 moveto +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<4D616B6566696C652E696E2C> +show +1708 271 moveto +0 0 0 setrgbcolor +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont + +show +1938 271 moveto +<434F524241> +show +370 331 moveto +<6465206C61207072E963E964656E7465206D6F64696669636174696F6E2E> +show +294 433 moveto +/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont +<69666571202840574954484E455447454E402C79657329> +show +294 476 moveto +<20204C49425F535243202B3D20534D4553485F4E455447454E5F33445F692E637878> +show +294 520 moveto +<2020> +show +344 520 moveto +<4C44464C414753202B3D202D6C4E455447454E> +show +294 564 moveto +<656E646966> +show +295 682 moveto +/Symbol findfont 50 -50 matrix scale makefont setfont + +show +370 682 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<4D6F64696669636174696F6E> +show +657 682 moveto +<6475> +show +733 682 moveto +<66696368696572> +show +890 682 moveto +1 0 0 setrgbcolor +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<69646C2F534D4553485F42617369634879706F7468657369732E69646C> +show +1563 682 moveto +0 0 0 setrgbcolor +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<706F7572> +show +1681 682 moveto +<72616A6F75746572> +show +1863 682 moveto +<6C92616C676F726974686D65> +show +370 742 moveto +<4E455447454E5F33442071756920636F72726573706F6E64206175206D61696C6C6575722074E9 +74726168E9647269717565206465204E657467656E2E> +show +294 887 moveto +/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont +<2020> +show +344 887 moveto +<696E7465726661636520534D4553485F4E455447454E5F3344> +show +974 887 moveto +<20> +show +999 887 moveto +<3A20534D4553485F33445F416C676F> +show +294 931 moveto +<20207B> +show +294 975 moveto +<20207D3B> +show +295 1092 moveto +/Symbol findfont 50 -50 matrix scale makefont setfont + +show +370 1092 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<4D6F64696669636174696F6E> +show +667 1092 moveto +<6475> +show +754 1092 moveto +<66696368696572> +show +921 1092 moveto +1 0 0 setrgbcolor +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<534D4553485F5352432F7372632F534D4553484755492F534D4553484755495F69636F6E732E70 +6F> +show +2019 1092 moveto +0 0 0 setrgbcolor +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<706F7572> +show +370 1152 moveto +<72616A6F75746572> +show +556 1152 moveto +<6C92616C676F726974686D65> +show +832 1152 moveto +<4E455447454E5F3344> +show +1149 1152 moveto +<717569> +show +1242 1152 moveto +<636F72726573706F6E64> +show +1495 1152 moveto +<6175> +show +1572 1152 moveto +<6D61696C6C657572> +show +1769 1152 moveto +<74E974726168E9647269717565> +show +2062 1152 moveto +<6465> +show +370 1208 moveto +<4E657467656E2064616E73206C612047554920646520534D4553482028626F75746F6E20646520 +73E96C656374696F6E292E> +show +294 1309 moveto +/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont +<236D6573685F747265655F616C676F5F7465747261> +show +294 1353 moveto +<6D736769642049434F4E5F534D4553485F545245455F414C474F5F54657472615F3344> +show +294 1397 moveto +<6D7367737472206D6573685F747265655F616C676F5F74657472612E706E67> +show +295 1515 moveto +/Symbol findfont 50 -50 matrix scale makefont setfont + +show +370 1515 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<4D6F64696669636174696F6E> +show +651 1515 moveto +<646573> +show +739 1515 moveto +<6669636869657273> +show +910 1515 moveto +1 0 0 setrgbcolor +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<534D4553485F5352432F726573736F75726365732F534D4553485F5B656E2C66725D2E786D6C> +show +1843 1515 moveto +0 0 0 setrgbcolor +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<706F7572> +show +1955 1515 moveto +<72616A6F75746572> +show +370 1575 moveto +<6C6573> +show +445 1575 moveto +<636F6D6D656E746169726573> +show +744 1575 moveto +<737572> +show +824 1575 moveto +<6C6573> +show +898 1575 moveto +<626F75746F6E73> +show +1075 1575 moveto +<6465> +show +1142 1575 moveto +<6C61> +show +1196 1575 moveto +<475549> +show +1305 1575 moveto +<6465> +show +1370 1575 moveto +<534D4553482E> +show +1569 1575 moveto +<436573> +show +1663 1575 moveto +<626F75746F6E73> +show +1840 1575 moveto +<7065726D657474656E74> +show +2073 1575 moveto +<6C65> +show +370 1631 moveto +<63686F6978206475206D61696C6C6575722074E974726168E9647269717565206465204E657467 +656E206574206465206C61207461696C6C652064657320E96CE96D656E747320766F6C756D697175 +65732E> +show +294 1732 moveto +/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont +<20202020> +show +394 1732 moveto +<3C> +show +419 1732 moveto +<706F7075702D6974656D206974656D2D69643D93353033339420706F732D69643D9494206C6162 +656C2D69643D944D61782E2048657861686564726F6E206F72> +show +294 1776 moveto +<5465747261686564726F6E20566F6C756D65942069636F6E2D69643D946D6573685F6879706F5F +766F6C756D652E706E679420746F6F6C7469702D69643D949420616363656C2D> +show +294 1820 moveto +<69643D949420746F67676C652D69643D949420657865637574652D616374696F6E3D9494202F> +show +1251 1820 moveto +<3E> +show +294 1864 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 1908 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 1952 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 1996 moveto +<202020203C> +show +420 1996 moveto +<706F7075702D6974656D206974656D2D69643D93353032309420706F732D69643D9494206C6162 +656C2D69643D9448657861686564726F6E2028692C6A2C6B2994> +show +294 2040 moveto +<69636F6E2D69643D946D6573685F616C676F5F686578612E706E679420746F6F6C7469702D6964 +3D949420616363656C2D69643D949420746F67676C652D69643D9494> +show +294 2084 moveto +<657865637574652D616374696F6E3D9494202F> +show +772 2084 moveto +<3E> +show +294 2128 moveto +<202020203C> +show +420 2128 moveto +<706F7075702D6974656D206974656D2D69643D93353032319420706F732D69643D9494206C6162 +656C2D69643D945465747261686564726F6E20284E657467656E2994> +show +294 2171 moveto +<69636F6E2D69643D946D6573685F616C676F5F686578612E706E679420746F6F6C7469702D6964 +3D949420616363656C2D69643D949420746F67676C652D69643D9494> +show +294 2215 moveto +<657865637574652D616374696F6E3D9494202F> +show +772 2215 moveto +<3E> +show +294 2259 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 2303 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 2347 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 2391 moveto +<202020203C746F6F6C627574746F6E> +show +672 2391 moveto +<2D6974656D206974656D2D69643D933530333394206C6162656C2D69643D944D61782E20486578 +61686564726F6E206F72> +show +294 2435 moveto +<5465747261686564726F6E20566F6C756D65942069636F6E2D69643D946D6573685F6879706F5F +766F6C756D652E706E679420746F6F6C7469702D69643D94204D61782E> +show +294 2479 moveto +<48657861686564726F6E206F72205465747261686564726F6E20566F6C756D65204879706F7468 +657369739420616363656C2D69643D949420746F67676C652D69643D9494> +show +294 2523 moveto +<657865637574652D616374696F6E3D9494202F> +show +772 2523 moveto +<3E> +show +294 2567 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 2611 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 2655 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 2699 moveto +<202020203C> +show +420 2699 moveto +<746F6F6C627574746F6E2D6974656D206974656D2D69643D93353032309420706F732D69643D94 +94206C6162656C2D69643D9448657861686564726F6E> +show +294 2743 moveto +<28692C6A2C6B29942069636F6E2D69643D946D6573685F616C676F5F686578612E706E67942074 +6F6F6C7469702D69643D942048657861686564726F6E2028692C6A2C6B29> +show +294 2787 moveto +<416C676F726974686D9420616363656C2D69643D949420746F67676C652D69643D949420657865 +637574652D616374696F6E3D9494202F> +show +1680 2787 moveto +<3E> +show +294 2831 moveto +<202020203C746F6F6C627574746F6E> +show +672 2831 moveto +<2D6974656D206974656D2D69643D93353032319420706F732D69643D9494206C6162656C2D6964 +3D945465747261686564726F6E> +show +294 2875 moveto +<284E657467656E29942069636F6E2D69643D946D6573685F616C676F5F686578612E706E679420 +746F6F6C7469702D69643D94205465747261686564726F6E20284E657467656E29> +show +294 2919 moveto +<416C676F726974686D9420616363656C2D69643D949420746F67676C652D69643D949420657865 +637574652D616374696F6E3D9494202F> +show +1680 2919 moveto +<3E> +show +220 3030 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<417474656E74696F6E> +show +220 3035 188 3 rectfill +408 3030 moveto +<3A20756E2066696368696572202E706E6720206D6573685F616C676F5F74657472612E706E6720 +646F697420EA7472652070726F6475697420706F75722064697374696E67756572206C276963F46E +65206475> +show +220 3086 moveto +<6D61696C6C657572206865786168E96472697175652064652063656C7569206475206D61696C6C +6575722074E974726168E9647269717565202861637475656C6C656D656E7420632765737420756E +652073696D706C65> +show +280 399 1 176 rectfill +2125 399 1 176 rectfill +280 399 1846 1 rectfill +280 574 1846 1 rectfill +280 809 1 176 rectfill +2125 809 1 176 rectfill +280 809 1846 1 rectfill +280 984 1846 1 rectfill +280 1276 1 132 rectfill +2125 1276 1 132 rectfill +280 1276 1846 1 rectfill +280 1407 1846 1 rectfill +280 1698 1 1231 rectfill +2125 1698 1 1231 rectfill +280 1698 1846 1 rectfill +280 2928 1846 1 rectfill +showpage +grestore grestore +%%PageTrailer + +%%Page: 3 3 +%%PageBoundingBox: 18 18 577 824 +%%BeginSetup +% +%%EndSetup +%%BeginPageSetup +% +gsave +[0.24 0 0 -0.24 18 824] concat +gsave +%%EndPageSetup +%%BeginResource: font NimbusMonL-Regu +%!PS-AdobeFont-1.0: NimbusMonL-Regu 1.05 +%%CreationDate: Wed Dec 22 1999 +% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development +% (URW)++,Copyright 1999 by (URW)++ Design & Development +% See the file PUBLIC (Aladdin Free Public License) for license conditions. +% As a special exception, permission is granted to include this font +% program in a Postscript or PDF file that consists of a document that +% contains text to be displayed or printed using this font, regardless +% of the conditions or license applying to the document itself. +12 dict begin +/FontInfo 10 dict dup begin +/version (1.05) readonly def +/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def +/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def +/FullName (Nimbus Mono L Regular) readonly def +/FamilyName (Nimbus Mono L) readonly def +/Weight (Regular) readonly def +/ItalicAngle 0.0 def +/isFixedPitch false def +/UnderlinePosition -100 def +/UnderlineThickness 50 def +end readonly def +/FontName /NimbusMonL-Regu def +/PaintType 0 def +/WMode 0 def +/FontBBox {-12 -237 650 811} readonly def +/FontType 1 def +/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def +/Encoding StandardEncoding def +/UniqueID 5020945 def +currentdict end +currentfile eexec +E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89 +699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641 +2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2 +5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF +9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A2261C63C769D2F4B60FA2C438AD7D199D8E4 +5F7E7C9A605C8CA14E21FCD81C9A515FB8DB6F99604534D06EA9D87FE0FAA852899C9D0595C7A97E +6C55F79FAC45CD38E87B10D210CE7501E88C8FCD3444354365FB893A12F596AE2C1E70D5819EE0D0 +87D10BF8DA96F3DABD5405D28C4228C6C31BA4052464859640933FEEFD8071C0C84CDD829A9B1D0B +A01F25A4D50EE2EA2B45160CA6333B2D2800306ED2BEFDFE155E9D9F9342EB8D5B0ADBF2460CCC98 +643FB1287CCD28ABA7B5CAB92EC39EE2E918990372B16F8487EBA30EAE88708B6CF33B6C015D8096 +C7CFE2F139F52052E3925C0D50FD64CE68236D59CB83EF56BFC584150EC38065059F3308AD6F9A99 +F83EF4E6CB13855C8175E31417D190D036B387D3952344A950F4D8C7781B307A094DF1ECAEE4D2C2 +FD747BC6F7F9C6BD0E90C19294F96C8C5CFE88FB34C477574A1B1630B8CC591529E59B20794DA32E +61DECDA8ABBD1AE956CF74012AA01D42EE01E861B0AA6897C864788AE59DEF43C493246FDB1ACA55 +4C12594BC7B33657A9ECC9E3D1472EF826073F632BE540C35FF6FB40566773F3BB2204D3A579A08C +CBC844C14B18C350F003B9DA23A570C362D6003893CA32F86F59B829C78EE3188B6E3F7FA81D7F62 +2825C639638DFB78B7AF1F500F5B450FA54DBFA5CBA277C794ECE93275A3DE0B452FDC8DDC2993BA +A42F28A636008CDCB03EBF71BDCAF35019778993443F88412AD2AD0D7155A3944606463266322DBC +0244B07DA1E9C27A27B59664E8566D7A54CC03E995AAD008B0A17E2C3EF61F720CE7F7788599C4E4 +4C709CD5C31B11107F16AD70B17B9AFE2E8CD922A7428DAC171427FFAF51067307FAB0ADB530E701 +FD22DA22C4CD3064067BD4F6089C4B2C87937DD426E4E9D2F60E608288BAC9056554D04947E69200 +61E379CF5E81BFD32FD37EFAC1F61CEBEE551B0851516471A7472C60DF89DAA9EB1DC5A67E479745 +3E69B9E22BAF4E3CCA4192D603295B018C4AB69D18DE52DFDF15E96B557F290A4B8C5B1E7A6CACA8 +1F2351B97ADFC36995ABA43803A6E5AC04A3C93495F6D38106B8B144449C07D1358210F9176E1565 +72363CFBDE576BFDF99FA329DD1346E83F79E06CF68250CA57A68931BC7F342AD295D0CBA17AA95B +B8EEB53EA6E8E660B814E9F857CECB14F44A43288B69A9E7908D55BF19E844359879D28CAEF1C38A +36420185D20DFB32C2E002202800E8EF3D67C5D50E919657CA958B538D537D503444865331D79BFC +40312068D72364503BD0CC84B5F30A74D8B5B6A26AF2DB764564FB65A6BA8F9051AE2B4EA458D46A +4569F30C6E77DC097356770362E6CF3F1661074778EBB44FF7D1E3B64FF75E77E11FE525BB121C65 +46CFD13300CA1F02D571B82A5825E6226D14FDCF27F06D87452A8B6C5DCA658535CEE2A795E58137 +D48E566B69D53A0C3B766E84C51EAA221C46999CC8065ADB2F129D5B630FAB1814C0C33B5AEA0EFB +B6E994D80941B53079AF96D90A0B924F9B0E319BED9836B8F9053F868363D3CA554CBB181863301F +8CB940872ED5FA7BD18CE39218B5AD8AC57D0F752D941076B1C64D99BE0DB86D7A6D96510D772EB2 +4C587F11779BD21CFE5BDE1F29C1EF9022B2B8BCD7F91153C845906722477829C40111D810480F3C +F62DE8DBA7FD86CD236E656618CAF6FC46827FBC4898EA7672F8C9971AFE43E0E01EC8B77D4AF48C +BF1210E98C1DB15C16D149BFF58AB0270CF015B107A3A50F5DC8F37FFB92EEC8CB6778DDB7CE4AAB +C464C4AFF654223006A550EB52485A23D2B4AA7198D3CD54418102F1E9A4FBDE37B841E56F5C2C53 +966DB9B66B000E4588282E3FB80C2C519339F0002D2F83C979EDC5827A3B3C8EF8810A0F9DACB6B9 +998E9AF6551F56313DC4011904CB979AA2D32B11A811BC248141E4B9734D9FB7982A5671002D8279 +CAB93ABE057474628DEFC95D43890DB1ED34CFA8A20BDC3D874E7679A396158E522ED0AB969A4E3E +C7E4474E192590504D54DEB7B260B7935C4E56548A7D121AC1F741F8CDF259EA1B5813175A77A1D2 +D30BA26F65EB765A04C09ED51F69F41551ADF399E6AA2FC09788137BEA4913F17B8EB838C38FB272 +1FDCB55FD65697FF0B850E7D3D1CE266BF90F7EC06A9A0876BDFE767D3A918B092FC78C775F945CF +1F96E859C03DBF630D9A940939654C3549D8F7921CB94EE23D5A0535DE9DF31EA0F937F860B4F220 +A99ADDFC343D7CF7BFA0B803C12C26403F0DCFFC8EA786D0D8A8D9C367419CA8AE41190CE93A8086 +583A1E6C9D70B612C84D87D2EEAA71EC2DC12F4CDE6A821303D5F6A9BBDB7EEDCD289E80FA3B75F4 +7F481B50719DCF4A142069393593B9AF9CCEEAEC56A35B8787193D7C88113E9E1E221D151E093B01 +9EF89F6118BEC4735103CC8003CC5AD1B6727B3226CD44C497DA7052DD681695DBEC3397F9598C91 +77701C73BF0594CE93F23D50EC5BEE2FB9DA1FC966DF148B27B28EE3C89526DD6625E2887F9FA076 +7C127C609EE315626BC14D274FBEA56528DC06A27B2D476D46E9E7916590B156A5DF04A6CB15E362 +45D77021767B6E5BDFCC679670263FD891446C3371B11BB6E1DF60F960AAB4149D7753E6A5C33810 +C42C8BFF4E935003388506F8278BD7CB672F132E065AE684DCA0B9064D01DD620E7FFDFE04F14277 +EFE8E60159BA0FCA3FE2F28B902D4AC275D19F0AC6971EBE827C4A232D87650D2688345BCA78F879 +077114F0463C5F058107B669566F8171E4E284D278405580F04BFFC9902784216E0C9A17AA9B2935 +E66E18A783F723BE044389B7E9D62AA36818FF2EA406C3C1A9D2F3436F3EE7DB8BE86AFA8DAA6A4B +1B84611350D8D27605509612B515E16AA843164D5D0805E36A2B9EF74C5F6A0B9D59A04B55697123 +27F4B1B30E9587CD103337639967CBDC655AA46E80D2CFD24BEB50815B5338E522B3A7AFE8362AB4 +F05D8BC52BBA9C5089ADA8C89529B0275AF422EB540D31A938B8740860756325B966B36817115213 +FAAF92DE63F6BAE1E0064BFBC5588098B61EB83C71F1C2082436D37DAF1ACBE186FEDC4BE7C1233B +6F18BEC5F99002D21CB7864E4811F7AB3C03003E1E4490AD1AC793BD28FCD5EF0E6CC30EF39A08C5 +2F71939B0CEF620DC69E31E39D6DB969049031B0C92EF2DB653D97F370141456A52985076B268652 +FA2648C792780BAD637C4D7581FB2D62011D57E293719487CF2D1F013CFAA532E1C2D39178D51272 +A6AF041440BCA174B5CC902BD7390C7D3695056CB4BD7791F9FB6D88E7A70DEF2C97869F5DBC5BD8 +23C517C7B7C39D624DF627DC9653EA5347BFDA80B723F05F6DBB4C9EA501D862ACE05B9DBDF21B70 +56FBCD8C6D4B85873DCEE6166C8B5ADC0316CA12D9639F361B15A42F00E1D62EDBCA1111972FA0F4 +5758BECB31DB38316F3CDFE1B41748C93ED58B67E9B57ABBED5924A6D53E99FBC9A994A6489A8BDF +13EB685548B4DC6D62DA7426C22227D4D43B6FFC7B5EA91C896730253E8941AFEE588359C2BECF6F +FC415B9EB6D31CCB0F6C7F85853E6449FA6D627A97A3CE8303F148393ADCCCDFA2FE085C6908BE5C +3C05AF00A6F02840206C3253A559AC5C049BDDFD11AD9B118403B84DA10AE3C470CB9A9A2D1D7B73 +2F59F5FE146DEDA60AE750F551AAC934621B4470E1BC324C436303E25F81D0DC3188BE0D6FEC5414 +C20E4CB18952E12CB6423DF7124627ACDE145500D77A97A8BFD9CB50D1FAA008E2CE2B2505A4749F +1EBBB092C347023714055A9B63353AF9E7FEE05BB54C9843698101F79888A91531773830C2C967B5 +88D3ACD2192883D5CE3962D51084FC653EAE2C5FB2DA41DACEFB5C76812D2EDB5B109677289CD199 +8D457FB1023A19AC67295BBC1A9A20A426B06A368DF3C5DD083CB1180D287F5500F2C635EDE157EE +FCEEC5503447382D15C748C1E35F68753992E5C90F900DE54D18F8E1B355D1076ADFB1F3590135FA +D1A36F028E44F48ABB149B80CA9A54614D467F8D71CB310BBC7AC7100261092DB8C5BFD39E0AC6BC +2C9D6CBC3A8C05FF8A74CB21608EC4A4CFE4CBAA2D056DBA14206106044DECF59F957EF8A9CADE4C +9B19D8D30DD4FDE6A9548E50DB51ACA73330142153FC36B69C1C8D5B26D0C689B7040E81AC2C864F +D7C097C99BE5953843E172C97AB5684F35FB03A725A89DBF371F08DDF40A1531FC1B676DB0E1543A +EC6E97D3D2E4AA3D5831D8B3C952ABBFA112352814FB6FAB61A0D680E6640F6AEC8426200CF61286 +F7422CB2F78C61EBAA36D47EC16D7FAF8B4AF31D090CDFA255D9D7C61D46CFB22A7D6E1758E71ED5 +67E00CBD8E8F468DDFB477F091A2F915627F22FF47B876544BC1F03B6BBB98385F009C20BB1AA2A7 +A78674692B8EAC2E3C8069B79E679338DA57F72976810F845BEB6B9ADD32B95D78E5E60F16DD1668 +9C05FD82D36A3115BE8ED494A74DD211D58A2CDF983FCB9CDC29BF7F0E29988FA23560EDF514BC1D +183F3B2A22C09FB179B47E05ADEF48DF02F31C29875D1915037B19407764A4292FE44E741651A8E3 +BEB5F0D972B6327090F664417C84F84FFBF0AFFF8B1D85C822D90730AB4140C42A51AA8B1DBE4398 +4EA8566040EB8B341CCE23FD3F69DD235A080BA5C69AECB9BC732BC2D7D40617DDA6B79FB6EE40C3 +556C7DF9B23DAD89E94054B1345DB8402AE679FC4655A4A776C0150463F8DB2BFC0608EA1F124E22 +1DDAE6026B5E5D007A7E4A0D6B3B0CF3A2669E67C5E4F01551966A7BC48F2F4B6A87E740D8095E63 +F77C7A027F26B52F2299DE5B8A2F6209BCF3D31CB0235F998F781E5CC81E31DC424E008D46EC0920 +2951E5684804A0592EA47D6C788A20487BEA2EC8F2E6C1D7F378B62DB43CA43C4B366F8B4319631C +FE9854F0E10321CFA3B01C873584863BBEFC23C72C05E695B56E8A52E89AA2DAB543834D34DCAC5F +ED08DC51825C5257AE59850D101D84F4CAA1D29FC932F9E0EFFBF7A9A7F3685F61F0490CD3CC8988 +2DB52A757A6AF4C4E67B407BD2316B1C0FFE7DC54E43C87B874F57E4903334E2140B011484863CDC +ACA331175F2CF3D72E0042855983AAF8853D3015E870FF0807014C31D55060DF3FE1FCE157324481 +2744AB51322444632F9AFDA6706E320FFE82B8CBE242A19DF00CE73EE48E25FF49D5871BD3E60652 +298FE3E8D400609E232E0DDC794C0579ACEF89E841B2EDCA50D51151F65E8C1CC3B01EF1870558F0 +BF5743718C3E068617E81BFE120C6CA16E0924BFC2541177D53671CAA3AB641C41557DCDAE1A3461 +47B5E999C4541B08B4AFCBC187AFD653D5B5F8386DF6AD8FE69E21BD0567DF494F736C6A184FA4DE +48DC9F347787CA96E2E00A296C2DA05C2AD9BC423E9CA428D7F1FA12DC9353A302FB8C529AF8688C +BB543B45B2717EBF8F6C497935F4F3BFFD285E0402AB7544B3CA4643AE5A8B5250ED987A95FC1F27 +5B9707ACD0641BD0EE2AE9758494F8D8A51DCE408A38AC20EAF0852D72D84D0C6BE973326793AEB9 +55EAC6FE0A2813A355DCD22F6F2CE56588D1C055CDDFA98878BCEB6A018DB22922D2B600A20F8184 +2E665DF41013CA0947C4237C2BD60A75E2FD1A3FB8C8FA19485730B87461AD466ACB02DF8CA24091 +4FB090B3D2B41EB6B8FF05E1A59D9FD668AF70BA5BB72778953BA55FC5F9F626043450E1D09BC83D +8605098ABEF884639A37809A32565CBEFB3FF39EE53D6C18C58C272BB928E4410E361E59A50F242D +69747A032617C52DEBBF62364AB5A96EFAF642D9D82BA679B1D70FAC10A4EB62FA5CFC308E86368A +AAD7E75948F43598CD1C544A0D4091374D7E88D4522CBE902391641327E888E7748FA889DCE67ADE +61699E7D77763681CAEE9B1CA8837B2F7EF9C18CBCC538C465C8E2DD34616953CCB6030A222C728B +834911C1A179E2C770289407AB28B303E724D97F747D6134B425216A64C6E0B60F633E2B85300047 +E4C90339CE030A0FAE31E830C8ABA5AB3386A3B69267351A7BFDD66356AE5E57FB2994452993E90D +E7C4E260ABAB93C37831856A650D56E44172FECA01D6C7C380F250B82473960D2A2A5FB6B4DA668F +46E624ACF7FA0FD4490F485D640A3ADFC9F8652E7A38CE5799F770C3606DB4B8B947F93967F779E3 +A3C0572F13A5A187D31D7BD12A5C7BE23CB6ED6192086241B76C5BA6983DB9C93E4B208D707D3760 +F03CD6272EF3A4CE89B8E52E6AC5871A3D03EB975759AB4BE239E5EC7842CBB333E692CC607C722E +185D3C39164DD320C6945629C70FF66A5237C0A9520A1FAD6EB9816069351AB0F135D90CC0982B14 +7D2294AE4A38A527EE40BE9CDE2512AAEBB590E134388BB171D0956A7C4566D65A9A041BE6C4F883 +6B3EC3D2ED1B48B566A783292B15B6127920D247D494F070BB20BEFF60640B11B276DDEEE49706E8 +B2B21BB40B7F00AAFC594C492C25DCA774E0B80D82E927448DE2E74A9D0DC7AC9260096EAF187B6C +D6AEAA6D1DC4205B4411122751A5B22688404EA7C5861730371FFAC10F5AFD4727A0E402AB5EA757 +606B75EB86A05E8F774D6E430A1A3FE2A37EBB06700474239FB1CFA05EE44B91B82244C575B52E7F +AF934B04EEB0D933FEB57EBE326D75821C8B23EAA85B583AED4320B7F04B9F2DC591091216FDE52E +064BAAA9C2C9D9714B95A4558C21F3CEBE624B5403B31508F178581AF6863083ED762F1E2E34A45C +FDD71660D626FF8648F5D6C5E580D4765A67FB6159EC8077A9F0A88038C8D3D7C77FF0926E2123BE +874F7BCAF129D55A5B5960F824BD1728ABCFCC51D23936DE9A25C408D786E44C3A2BAFA4423177AD +060D21D38E15E23EB6FFC0B4120E814695D423EEFC2744A1FC81B4DF89D76F0A6803D8B14E75538C +AAD03A72517B86514F6952F6FD619D9E910D980F00964DB325318C045BDF79647F453D4A5CF4E61D +D5359782827229310405FBCF6107C3AD9DDEF9A9A339D5D5A6EB2E7838A0A43221BD62CBDF732DB0 +A638A52016FB35BA7761AEC846A023D3BF2D1BB183543E81EB7CAC1E5970CDC6F068C5EA118C7AAE +528D1396E6DC939112DA4460C890EAD5C01BDC438F5BB734218BA6270ADD0DC1778FD8AB16831D6A +302B814A1A44B07EDC65956C9E6CF4875DF521F3CE5B422F71081B6D69BD270F739095C9E81C0377 +934A8BC6390C420C4E4CDD9CF7E32544C68D884E15ACA3BCC07FC8C132D8FB9D752C15D75C52C288 +57E2EA461A6FCAD90C56843513F74461F18D7164BC597A28AE4BA7C86EE1703535A9B9ED50122627 +71FC12F102E800E0E1AF7BB46681BD2B14B614CEA91B7B2AAA35235DE76C0E113C92688F8EC81277 +D58C3406778E1EC1CC15F1CD9A137C8FFDAAB99ACE3BFC782916F1A877170589A92DC921E6740A22 +B84DC6BACDABCC76E64C79E3A588D80F8F4D376E1B426F15751CF7391102102F0AFAFD8B22DFDEB5 +48AEB5F30B1673023D22054A13391A0EC08DE6E7B685A0D031AABF20B7C62187C0284892D5EAADF1 +21BA28263EB863D5E36EA9C06A77CCFC0E17F593961591F84D82AF823EFE41044C8D606FEF83CCC7 +B0E961E7994DF8A3CC36B209D953E250ADAB8D22D7F2B4E2C9CA39EFA2D93E56195C1560E30A5190 +CC5B17FAEFCF250DF79F6B624A4B917E11C332222FCCFEC4F6A47BD9E75DA9854FC3F7AE554E91ED +DE144D7AEF38A0E3EDB5E5A5626374DB94F022C8CF549093041DE00D7269B7CE544E748439BA2870 +718C08E58FB4A77D93EBC04B7957D272AE1601D41BF85A2BADAA0DF73B0D3841D4839C85677FB2E1 +5F1D6CE592669FF4BBC9C69DBA334DC37706F2F6BE83D5863E8CD6A30C08640AAC4C233684E66B4F +E6B62D4A8BE9D531E47BEF5640D9B5C27D990092BE1597F6995C8A77BE9C18AAE6C1CF130775DDAC +41D34438FC7AD8E042CB56CBF2944932EBA7D053E9376FF398367450E35A1945FE23E05C921096A1 +5454721FFD0F429A3E06DC3ED36F1C170BE79C66996EF8337AFF85B90C5D3A4A94455AE9FA32E211 +7A63E59001F052D5F6223125BFAFA40901E98960ADF7BB886729DCA82FC3B8CC52B37FF2517299E1 +D769057F8154FB95582F02CB0BECC873A9C71796ADBD3E91324FAA94F2C41CF57C30B5897D031C02 +D256C909E080E70BFD1F32E69EF67031138C2DDCD1A8E4B65E485C23C3E450ABDD9815512D6F34A8 +4B9DB715DB2C7A93BFB424316E1AA44397749CB01088428F149A3B4324737ED9957FD388248462AC +1B2610D72BF5C073ECA567E7385CC959E37CAC7E05470160FFA5A9F63B8E9B082937E911586EA165 +374938F492EDF28CE6020953A5B5CCEC7737F9D9CC8538C4339567AAED3794ABA3B9F4EAE65466E8 +E326F6C399B36355935FBDCB9972F10B13494DC25097FCEC5A6398F275C8C151558E74C5175F7BAF +4155E36B733F75CF9D5C5979B0764F14D8306E06BA24BF791141E404C69F3F8FCCD91B9C58C2C671 +AAE7D4F9E5D6414E46ED633A5F78AA5BF04E652246A066EAD9E582B181CC196EA2D3CFAA383B5D0E +4CAC9336E119C08CC6AC55CBFBAE147C623B400453BBF447E96DE036FC025624384359EED7C7D5F7 +858DC0521377CF647A157FC3F188DE5EEF094DBA125510FDE34C570D7BE76AB5DF0A28BF45DDAADB +EA7EEEDB936332DFE93081E0AFD3FDD46BED08D6914B2EFCFDC41662A33B90B03D76D34F48D30FC6 +BBBB600E90E6AC7243FDF026762A44B4D6E4ECBEF48C9D7B696AF29EEE063E557D8FCF0F09E0136F +45D17E608DA36E59F2AECF8493F8D62536119B5F7E1554DFE3F6E8D7C9A2C6F557D18B4AF92C9F6E +050975C3B5C54F9B5F4E39D600B6FA2CD6DE203A174028CBB2A201AF126D1013C229BB82CFD013ED +199D01E51EE2780FE896E01C63C655087A3E61A7F1029FA5E97EA1872F1B45F22282DDC317E17926 +7368CB52DA9444F6055A3C653659CAD2A1D8712BC2B1B32C1DC6906D957FB88524EE066156ED6BDE +B8D832F9338F9912E29A250A8C4674E667C1C278B677AEC9972BE83CBA3FB779893FCB8F81A323AC +91474BA2A2334A07BB5628E905C518E634F6761A3289056F83D5DD7B3890987EEE1C18FB2D379CC1 +905F1AEB3B3D2AD578F0D6C845D2D40C4BCEE3F71C90E68E5417BB8CDDD878D83BA80AD8485F4067 +E5C3CABF28AB56CBB219C0AAB8FFC6C7E192BEC8CBCA1459AE4450AFCC81B9548F40CE2622E5A7C2 +81F74DCC02DAD57EFD92D072318DDF05BF42F1EA8163071E23949B0179CF7DE64677CA99B23CB926 +B3E294194EC13397EA1DC9A5E1CDCD828156CD71F81B64167D4FB01E6002713BD8AC6F82B20CD369 +9C6CA4704DC5C65A2D66EB155B7AF1C9BB46469416FB49C1C7E17A30A5F045271D7DF3FFF2F42C6B +470701C381E3456A500C6BB3D0E47B4D91C5F34B49BB6272F1F8698B307D89EDA3A1565DAD1C0864 +627560CF922DCF5B34C67860352390B282F95394AA2CDE0E97CE3ED39546A6AF1C52BFCF81A29BE8 +2C47C99E8050E4889E4575B75F39E662F2DB7420673797E2ED3D67CDA7AE2C15D0A0A794D57D168E +BE13214E89E0209AB2C0EB7784E9491AEFA3C02D0DF3AE5365A0FC4AE023CAB528162C7A1B173664 +9DFADDACA8DA5FA18B7D6489E4229E9E24D38A620464A744A5C60F6F9D334B908706B738AED18669 +8A8B278341FA4D65A0A88680BA484694921512F7DE93337FC1C02BBE6E64AF2DAD07603279D87329 +1D1F4D39C1DD6D89C90F65240F4808F6F1115CA55B88E242565E59F3BBF1F10EC7B88872E9AE61D4 +4CAE185463EDFAF7DF63DE4D2207D307AFB61501892965170D2945846FCF5973A1D458607F50C15E +06E5BEC715E0C156259AAA6C735593E5564F65F443B78CC7512EC35A56F126DF9D30974A40872E42 +65E1AE5FD483CFCBBBA26DEE426CDC4721F19C3FDA86ED7AD4FA1120F63669BEFE7002B128CEAFD8 +C63E8AC09943B6CBDFB3D2476A026C00A8FF81B1F651B97F310C82ABA5F388CC1DB5AFCFF5996D52 +52A6A42FA4D972E41EE56088F78CB966F9051171C472C774879AECFFF08BFD9CEA40D7C298922ACE +64F28C14E0B81F4DCADE81D71DE3983D87D905192EF13CEE71B2D3FF1A88AEC671EC318917DF98A3 +C9054E372D22A3CEC82FCC217F47319A40900312F6E32B536B9E7A7FA0837EC65CCDB5FB0D414371 +17596CB39D9382262DE6E65379D3A9709B2CFBABF5FC5D5B352425F06F88CD31012A2A4147B112F0 +C1C0ACCC808CD625E0228EEF66661F70AF96D3DCFECD402700E4F6522AC9A856DA466D55C84F65BE +2810A1565163872D62EB81333A698ED7B68352CACCA2D7AD38AB55C19E4F5582F75818302F5FDADF +1DCED09D94872F2D48FB636C8E38C7563C72C771A08C6B1F041F3532BDB39006C89A33C09BE1E3E6 +03622D891F98010BF1DE5355F557A1E09448D486ADEF565705277B31B8BF2B86761E32631E3435B6 +88B79D566F1747BA456DDB43CD239FB47FF7B425EAA4C657C8EEC26EE01AED07CF916E77D53634C1 +37AEEA009C6B515B6342C54BE2C7B95955B1A9DA277A0ABCDA2346E88018C726F481F71D6011AA42 +F8852F2E5749518FE3B3AB668213FE1A05C10A1C53953D75312631D6BBBA01D418199DFEFF8CF548 +6109B099FE8E2F606165FE30F532C03567785D5362AA873C9D3EECEB20F1945D55F49B0CCAC84967 +59FCC7292E46938943C262D78F3212D3F9D0F7B103157F423D71B1ED54B2A603F4C269029918F238 +EC6828FFCEC66009DB9C9E59534EABB183F31D7AD4C57B1BDF0BD2CE5A421882BC10CC1BCE6A970E +2B586BB221567CCA483989DD0B8DEC424C1D1FF042DCB7834423CF244EDA28D2D969B17440CAEAF0 +24A6119DB010CE366821AFA424D1B8299609C04148275AE6E5257A7ACB3C766C747CE99CBA2D703C +F19B7CF301B634D8B613DDC4AFE4633A4D77BFF8E00CFB5E289EBBCAC90A24307E7941EC1685CBAE +400CADD876FCEF7F6557EEE167D2035A05120293527700DC510B038A496BE1D5CBAEF24ED39F7421 +1A93AADF22214ED606A80582485AFE358E3A46D0671148998A3B3BE209467009B43400870359D418 +9A8CEB4D5866AB52D16D9CEB1EAB71C07E6CAA34B70E3096BF7604C22C40D5FBFEEA616DA3BABD59 +DCDB97D883FC8742B8267A16A99B7953225F7144568D566E64542C92E538AC140C851E5D295528EB +7CBB49909B1CAF6409C9BCCEB325468FA0B5F7CB2987382616B477CCFE4F4AC79E4A6F7165363543 +F04DE5B6F6E1C2E910CDC3CDD6C4C92737198F892337DCB6647BD226C820AC99C65D8E7772BBB74F +E65DCAA8A22C33BC168BF48E40A82700A3A7668C5A9A71E397ACDFEE7D556C5C19467B7AA69C260B +727407AC837BDB7D67DEC055C1F45D8BAC61048C45BC9FB3CEFE7549EAA2992D2EDC126FF7A05EAE +58613332A2BC1465B2BC0429162B907D65F793D236EDDD8D35405866D71B25F62DC4A7E06D4DEE82 +840ACCAABC0774F8A63E9C0F7FC980B3583E7A8B01C46590E3BC04EBA565C2EA94F057D964A78A90 +EA9F52ABFD70F84E44E434BD10A42E98C794065724341F907E35D3CB257161E01C7084E3A0166D15 +CED65DA7BA87DBB2EA33D39BD99AFB93D3548358D08330E807F8552CECF63C84F805205491BA3A1A +622E70C232FADF3BF2DCFD6F0539158D3306506F150B0518371912A25EB96163D73E9EEED42EDC84 +D688BC7F7708D9DCA348FAB4DF62E5809BD094842D0A31DBB7C4B41F94D946810C5EC10B69AABC2C +91A59500B2E5D37F4755DDFB7AE4ABF757F4C5BCF77C7F95E6A616646456FE8F18407080BCABBFA5 +7704287AD26222DF91AB2613951E2D679472F8ADF06EA2A20205EC19972299A78BAC52114334470C +5F5890C2F846B4C6042D73945127F2E3910ECA1C4CD7A16EFE4B4BE38A15AAA710682C3836A8CA83 +FD384970139D8B46FB0AEBB002DD224199672FFA02250FBCFA4E649E335428FC71F50F45E498419E +DB0E970F46894A48F65580881C9C4250FCEF65C9B28699408E18B26FE6DB7F1CBDB767564E73CB59 +54C6D639CE33220C894F36E70F71C9F9AA3FE2AE0AA0E3F2E304EC5ABC661675CDE2E70519E4220A +E26FBACBD01D5169EB844750753E6CED53E3678FDCD08AB93E10067E9C64F38B40B76D99B6CD92BD +F4155A1EA5CC824998B59AAD06E09E5F15EBB2288D66EA71B296616734FEF2796F07FF0D8B047074 +A1111D68B99C2B70FC56E74A51B062F4998ACC85B1943C9477E436E5CD7AB18DBC898D21BB93475A +623BDDA71D7B895BA2D4C10F4B90BF335126F4FD57D73AFA50170F6B3C364922E551D40E35DA75FA +891762FA23401D39260F2E92C7807C746F13BB35CEF9DBF2E76E66A72FEFF095DA482A4DE8A42091 +7065736CF4DE904FB52E649A32255E2030A7B31B686353492F31C064A3C4B0448C4BFD44B8E15384 +FD809B8761EE26A7DFA1758D57CE4F0BC376EB2B3833534B15A83436BA553955ACB5A7A66796AC5B +92DB5388BC53EFA27508B08E82821E5CF669BCE52BB860780F749B4F38ACDF5FF12726BF3EC2743F +01014CDE96FE6B4C40A034E9EAFCA2A35CCC776C2669E6AD138070A40F48ED79136D7FF57E993E09 +B81C543FBADD350FF5B5F7A46F060F88E30FE2D8233832D18B6C323EE017EBC1DF5C838321CDC8A8 +4CABCAB20B60A1A3AA028F36EA6E87C850AF8AF7CD50AA6359038BFA8818821D02CEE8F51DAB8C05 +F7AE9797814D97F3DB8CCDDE45B21DBB15CEE292FAA534A5F317B357F4091F3DA357325B8B9F5EDB +45865415973C143E5E5BAA483FBF2D06CDD4246675EC58B84C6AE65CA743117FF00F229243772561 +31A7F2BA26A9115AFD96C18216CFDF41B7220ED0CB3FCC26C36380007B382A02AEAE428887DC8BE5 +FDD630AC57EE3DC156C7B8B29E687F24442E35CE10BA4087295A641F7139C831F7CCDA6CCEB5DAFE +537CC1A97C5A337D3C48A6AE947F58A30DC08CC7B58DBBB4737AD52783C573FC1E9408F55495A80E +7FDA61F0B9C4F090158F1A416249EBBA936C27BEFDEF19D1BFB839EB70576A010706D8B95657B218 +9C2AE04C11EF9E57FE09880273761FB4302C388BD608FA0C7F00F033C9C00F4E3D5CE2D903E0DA52 +E69C7745EE9FA75E2AD93DC6CB5CCFCD3782A699B807AFC36AD1F62B05856D5DFD6F88831B90EB3D +CD523582A49732E3FD7253126D39E8AFB8458B5F7AD7F94A8DAC13365F433C857AF4A42C0A08C4DB +9887C4957259ED22D13CFDF5995DA957EA5A0F620B0214FBFE08AB6D552DBF048D62CEF6EFF12F15 +3511ECA7833E0E3E95F85E6AC0F95438AC4C126E1F1ECF336ED31CCA7EB216D279877123FD9FCD8F +B5E52B587CFFC4428456DDCA816819A8A4A211D8F1629E5D42BA4C5C356E580C8A22C61D987552FA +A97893816DA73D423686E4EBD44375C257F031318865A20F22115E72BF1EB9F93AAA169C140A33A0 +6C35BD4526A38BE79CF40AD1EFA10411E8F3300A8A8B97AB140EE6734E1BEE6C8EE443D698D34159 +97649C6F10F20ACD80236422E215E146D744A262DA3FC88DC0D86FF66512F49D3F957D3C5CFFEB42 +4823509F33F155057A4C6F37B52F4667767BA94F6B8B62856B553F307E5D230C44CBFDC9A97A45B1 +39FFB2F2565EB0E22026972FAD0FB7B9576FB6F368B61979943A398773600E7EE1DFEFBF26D45D40 +BDA66EBB96A56EE9CAE0B2420C5DD83E24DBA9FF885BB844BF3D2BF93B07325DFF60C0CB5FDCCA0A +C8FB5A2E119D5AF26E53AB8E3B428481C2871DDA26EF0B621CD8572B3C664BC7AAC01A1D05B98F79 +1A7080D294BE81099BDA7982432F3DFF4775C44D23F4F1B2E0162B61A8B2CB5EE8564BF98E2ED403 +2219085FE6194C19DAC98A421826CAED7F1AB1477AB327506010217283894235D7DBFC1153D5ECC4 +8AA7293F19592B4D7E95FE55151889BCD1D7FA7DC2370D2DFE11D7E4EA34B5C7A8E73BD3A348FD38 +9EF45B6167FB90BA44C23E912F9A4F2FC0427ED070592F7110183BFDB2C400393BA7569058227926 +351F07FED4F33633BA03A72AA2DC6B598E49B96021DD868DAD0F352E5722FB714F667C15C68D49C0 +3D822D82677EDFE86FE9668E537DA284068C9B0AED83074C92A5B939296D505B837E6A9DDAB1AEAB +7455A08A114C2222B339284674B74BF4CA9EE0C020BF2A148B439C71C6BE51A94CB64FBE4A7EB295 +5A455047CF5CB348B062ED4F6471CBC3E9ADD9BE9B96879AC7BC71BCE02FD02F17C6063985A5E898 +3D205AA1489DA13C408990ABA1C54F2F501AA172F530480D789C848118C0A74EF98D5F607A067BAF +F6030D887AC6A6497F9A0B38F9705F328AAD4BFBB634F739386177B07F22D5771282444E5EE17335 +B4D0EC86117C697E79A5F4F65FDC08E4904DAEDAB20067EAE2448FD4301849E456D085F392DD1316 +7ADF75CCFDB723E2904A9C0C976D6B84DDEF9D92B0E15FB246C3ECC2D0BF314CFB957757B3A3E8E5 +801F520644E4601D291DA0F7507C06F3B9BB36FC1C70EAA444E14E56C0CFF06C7F853DF36DA9D8B6 +AF2544B853DFFF535A7E5C6FC145250CDDA229956019659D0D253A19A7B51A4E538BDC01F74D7704 +9949C2C97C7EC6392C2E61CCC0992B66DAF1AB08551063E53180D2A67DE496716CCBAA45462D9F91 +B66A22545962DDAB120511FF08627131B95E5DEEB8B4DD9643E7B2AF65C0FDCE11F5F1E8DD468DA1 +8D41C8C4F00EA73836F4F70EC50FC3EC6D358C0658A4261C6D15A582A2C7C994E7882E661855B352 +014576858A265FFBC425160669CE159D07EDAC04D060B44E5800A7AAE8E339C29B929AA81D2F515C +46229D2080D5917AB20AB6B34FDCA8E4AF64ED660A3173786FB1A1D005D575C2A5187D3F7CFDC94C +CC44A38C5CD523E9DA726D8EFA6DA7B6131DFF3435FEE838B2C7D6B97934295F06202D307FF78D90 +6699CB9C5BBB10D1D4DEA5FDA5BFB094E704607083B646D37F5DA1FC7AD21B813F44D8C1AFEAB666 +55AAA19703BEA2E77DF3BF350E17C74B3447A452235919452B5175570A006C7680AC05E8950A62E1 +1D7E3ACA35A397D1E19630D094A86807593C97F4C484E4E06BCFF708B6DCA972E3A0009E1CAC0EA4 +141530F5C1B8AEF5E1B933F37FDDBC4BE22B74FE346D1A3F5FEC0818F8E61765568A2AC04713E828 +F98C449D9A1CCE52D10D61DD8BFD084C8D099A75D89DEA64D5A7CC68BD5B0593D97953DADA976383 +F5015915618AEC56D71D1DCD55B89736395C609B315A3F1E1255432FDBD37F38CC43C354FB4B7C44 +F1A7318B0B7E99C3C08C33B953727B6A6328051783A0A33E3CD9E498346A3CA6A77B517096EDD52A +E443B87643A646C3A7BB97F742888D33F9B3127E61942F4103C1DBDCD8EAC8F9E259773066736CA6 +53CE57E8822651261D847C131321BB9D6626A1AC50D047C0BA47B411DF2A995545BD68EC0287CC9B +31D5DDCA8755EBEB10ACCB3903AB0FD5788E984220443B8459E7C078DA4289F1350905881AD6DFDE +C47302B0ACB0D4AF8CAED02B4B70DF3CF8FEC118F0FC2D3DDE3E494CD160E676E300BC464BD4400D +B50EE43B314E0517037BF971ACD7CD327CB2134893B8A0410E68DDC518F5DEC966C7884CF5FDFE74 +723177F20DEDC039D879056CAAB4BF045062D3904F615C5CFE109AC7A35599C94024B41019B9AFD4 +04A80ACAA4837929F5C9317680A13D157A03B59A5588DF79D2E113F5F51021D6F6F90E8BBBA2C252 +FD10651BE80BAFD59C53A3367BA3C28DB6EB9DABF1EA99F47B503F627E15DCF3FD645FC52C5D5D0F +2F07DB4C25C0D1E1C00146E1C4D973E613CCDBD3F9450CC0F5343D79F05E9492E86A1BB889ADF405 +03BD7F3E7543436859184A5B20BD8A172F350D846B7570803990ADAA48D4B9155A2B4C4BFBEF1E1A +065C08E03928559735BDD442FF1E83E1FA20A5DA57D8BDB2FF5427C034CF0128AF111E6E73099E04 +6E0C240E80A73D7BE72B87834E45898D475521CA3306707631F5C6136199F354632D1A085F12A1C7 +C473868B62E534D15F5484323E63D0574196A19EF175214EB35A90873EFCFB92D6CF68761D45E37E +AA61E1A1979A82009507CA193E44B36A806486665CEDBCF387053ACEAB979BD35D30978FC7659ABB +E844F4ECAB3303318ECE80777A5FA5A9DD91B3D06804C4B4E9B4EFCF07EB89866D0DD8CA390CFD15 +98651417114D78776B1A1D36B4BA17746D6BE7FC123D473EF1EFED1C3BC1D555F914536869FD5B0C +35F9C83F65B0E6BF7A627B9202D787D72C600DDB6BCCE613D88492E13CA0AAAB196E8A49928C62CE +A4FFE2D0208EDA334ACF47F20BD793124D2C5546C03F4A364369A76A0425262F9D9118AF54E37D32 +E33AB25DD533A49DF5FBF1BAF4CEAC2D9D378CDCD13B00FDA432D9042F623DA41AFB80699B5538A2 +5403B0B3EABEC9E8EFCF42FEF3EA9F91766902CD206B0787C187D5370B60AD6DCD002DE2DE8DCDC0 +B4719A797C5E26BAA67665016DA0D967FA1346F9588AEDA174CA001B31213617FE19EA218EC23597 +79D979E2663166489C06993230B0D07973A117C4E3F4A4C93CF8428248DD5389414D679C69644142 +67C7FEA17E35B0CEE456667A9B1875C81B2302BDDEA2818D6019FC1622A82051F60584ABC904CD91 +8676305DC03FFBCC64FDDAC8D8AA9CE2EA00D6C97BC63C8A617DEDFC0E40775649438E9F61AFD179 +5E3B20560B01BE5E0983F136CF48AB206954E41DEE0D9DDD953DFD01CAEB569151D6BC0DFEF29D70 +FAE3E198E7EDD8922C0E0BCB8BCCF1C016142C1A8B337AFA7A05A9D7534B184BF3BF827F371E9BD1 +9A71244ECA1BA73D484CD2FAD54DB2F0EEFBD54B536EBCB5094E6BC2F5B2AAE41F05B4B311115876 +ED42C34F8E643B53372E3F6350DB8A38445822EA9A33E27FB0CC42CEDCD1FE2FDF723FC47C996EE3 +56C402112F24D0AF899B2D00BEA1CFD427998BD22B2A09046D6737814448ACFB10D387547D7009FB +384AF0562C85694C071584236D0F1F3D3FCD0CFB38B77C81889061E668BA7AB37AA60F58A3967DE2 +6F939B79CBF10A9DCC42852561D8D6754F1B660D216AAB1E133FBAA321C56E2584BE5C9BAE20CCF0 +0E8DBE6D9C2FCEBEBAD945C3C04101D2387351F132628786F6D9D4CAB83419288D31F9BC600D9664 +12E6AA457CE6CAD26A4C0671097B98C2384C81DD8B9A3222D4F4BBDA7017895C3EDC26662779AEE7 +40D9D7E24185FB821970B0A3A94041A69E4805EC88EE1EE521981536F2844FB8F5EF645F67D42CE5 +148E2DDE43AD5AEF200EDB3A2C7866C98458A92666E5F9E070178BCC39F65A893102A10564AF4E8C +AAA5075D2F8CD7FAB0401C03AF299EA3515CC93066744EB5AF7CF0ED06675BF049A6E3C211A89E16 +DE5BF0445A7CCA6EE8EB0347454950485D884606651E5887FE8B24323E2AA16DE22FC1FC8C4F06A8 +2A1FDE5758976024068197E1F4506E4D3D8A16D40461A4586338B374A592DC60334402F76388AD6A +457DC3F54E6169CF7AE3959676E966A45609621055EC3AF80E182633300A4418E34A66DDFA6B569E +5A13C9115B5FD3EC1CEBE50FBA247F60803AA83976F00117536342DC3D9890C49B2AC701D370E43A +955118967827760F7091469C5406F08F18D7E3548148CF0E312B1DC71DF67A5E7A1656CF2F47F3AF +F3DD50FFC2FCDAB7177285B29C17CA43019F62AC6FBA52D1493ED7C427526470ACC8389BAE827759 +4958908F517B2863B83292EB5AB3F57FFFB08393CA610FB1FE905D88A0A16AC395E2A2A6DD033D6A +0D68992F830B2E1B95FE357BF672716E88FFB92FFC3D62945D1EAD22BC68C51EE0E10A43011DB94C +44685A5C4576F6EF44CBFB45F2A4BF110A01657DB51FD499767E78058199B31DFD60813F1A344F86 +289F9378231D5B151C92385E3650B4FEB1DC91018EAB8474CBF69FDC1496A4D078D2C351C8196451 +247A9DCF8117E5B637371D8E22E248C64D999015C3FD2311E9950B8EE0922FBDD3D7BFF766BFE9E7 +CE0BE12F318FF2A7B5A9C6D00A54401609304ED2C55F5C1EAC3D4B38355BBD85D66D61636FA6E30C +2E82829376BEC979A6FEEE040E452359768ECF90CC539A546F17AE906C76F14F86FF697797322B05 +1EB311A759FE260C1EEE5DACF383816AAF1294CFFA7BF87A4D9BC595EE8F2C2F86FEEE11AD959D86 +F22FDAF4CEC098942A57E57813A0FA99239E994FFF353C1E781D666B8928CFC648FCF0869FC68468 +BDBDA7D280DFAB8B0B3A4CA35B074B686DE8D372C61FB32305169A1A9912F6541DA16CD6316A6EA4 +51524757BE5CF6E820011BE3859FB8B8578C100FF029680E05F0E0BF11D33FE19460C85EA5E4C0EF +28E29407C8AE6BE01CFA0D5022BF9FB01416FFF722A784DFC8FCE330EC95737A854471D334FDC58F +AB42867A7B62836A8B56466E9A6C1247D46EBAFFB905CD4321970F59FB8D6FF65FDDD34BF913AD32 +2E68455C5FF2D23C1A5EAE687F259BC982B6A384D35440F7C693CF50B9ECAC0B5578CAEE87588B56 +2EB6B7F42034C9F2E545EC866316552354EB3728C7D26527ED75174EAF635E048B08DC5D23E88981 +070AD5641A652F2344956E9CF4C16E652A99F4A644D1787D6D36537489DA4D74E61B2FC4DFDF1D1D +9D58F9C26C5EB63200526AFD168AC57D5611ADE4D4A382FC28BB60F9E7D626A6C67AFBCCD1183C5E +3CF2EF210D0BF5CFA7BB10FA3887BDD4CD96EEEAA8F9219AA2F10ABC0A960C3B57C0EC0313AE10CC +FF1F522124CFC8D2D49BFBB0C193EAFFC5B48FB3FF30B21CB76F0A4C0F1377C9223145BB0468A5D7 +1B9BC25873EA12E1C60334571C67385C00D0B570D3FFC6C7FF0DE62C183C76AEEB12DFFEE1459E0F +C818C621B8D12FA1357E2B55D48935D70BF140B4CFFE8813DEFD479350B20DC2EB1D3CBB1A2D3DC6 +EE975D58C89D61FC50E6A0197DA9A586B72255023DE47DABEFB11E8AA02414C2FF6258A281219B9D +DDFE41BA7D7977D0D6F18224FE22F7D4E9355FDB35BF7ED3418F4F68D093AC48F7D8FE4194FEB6C8 +0B9DC1F74E023C604DEA27089F98C3973FF9F4AD7BF7BAE601DB89B08D5D8139B95EDCF6C885FFA8 +B3E4B0477E7040225733826BACFD1EC4A0DD72DC41734856AB9FB700DF83CA2CE812913BD142D84C +5C83C0B2583768198AF9E885F2BA74877A414233207234AA5F18840557CA11682AABDE8993533887 +7C6D404BDE4153C9827EB16D66C1D73A8143C8A2D3604FF72CE579FAA3C5224BAC48EA83BA848429 +9472007DE96466B5B29ACC7C03B05DCAA38A48BFF9F214DE43146AE4E04FA705421917F99BC54533 +F0EBC01849E396216B9F0794E6F6C6B61B52EF1B1950C0FB609895C3C55FF574163FC8B6B09E66AB +AED1810E698FF37CC1F926B2CDA3B48C7D77790EBD2D514B6F385D397F713EC3AD3954EA9C846158 +6031D369E8B99E53408A79D64C34EB5A56DE8A67DE91837960E98A66FC04DFA0EBDE21DB003234BB +78665B039D0A469A0221BD541AF7149A2A659C300132C14581EF766FFFBECBA8B58A5EB3F95446DE +F49AF863A8113D17B2E7E6ECDEAFC3834D4DF900E3475596E86FBB4E2974C090DB4AD61A737D611D +92B4535AC291C56AD8B1C031D2F9B505BB77517B737D70AB3723DB52AE2ACCD5DD2F617423ED3CC3 +9CA882EF41757BF7151806A9B8B0F312808863E3673FB54DE939B35CDECA7FBC4DC3BDF5A5F47D35 +E345916C39366C8B4F439CE1C6F1835C320BD1E67375B03B5DE18C93256F251761A4C8CEC01019C0 +68E34447BCC503B9571FE8000627A6B3DAD5854CBC0A2D69E5A8F46BC78F6A7B1422334EC7A98ABE +FE9B83E01DCF3C6C9273B346F3240EA225AE4A4083CC7B0EA141A0773FDE940768358EB4B13D82AA +304A1386D450C1C0C6A7D5A8FD2BD313F78F85248B5196241E31E5595F3BC01F37700A2DD3D4A0EE +2DD01A36569CD507130E8F5B1E96CB560BB7DA15560CCADF3B2C9804A11D9E8055C9EC70E48C1D21 +3EB756A1376F2EDCB7189D78CD3D6CA5865537EEC31C17D801605EFD860B0B629472690588D02575 +02C6F7A75B9A1C1B397781329832CF3EC43C09F1559CD562C48FA9500295CD3B0A790DD3FCD4684A +7C7AC49AC9BFFF36B39A9FB148BC28D37907433943CBBF0CBDAB46D3EA86DC8F81C859C52D15302B +94A9B51C199B7104DEEC9D769C2634CECF8B700CE9C04152CC59C9326BDACBEC4312DEED92DD087A +1C4840868D9F97CAC046581F762F75E8D24D6445370A3F1E0AE74A6478D9DAC37E7FA5BEBEC0A1E0 +81AF89C1BBF7F51E3E2E22C8C405E8671BA85F1BF0DF79A465DAC7EC07F731E00632E017D190A99D +83E27E5C2E63D7DABBA23B2E88334C63721AC5A4CBC5D45F4C177259F34C2EADE01FA008AF65EBC6 +01D8DD16436D86AA94C99F3CC0A2F87134E73BF22F108B825A8963B49C6C685474AFE4A542C8641D +C0375D7EFE9AC1168D9700459BE52D0DA399023E141969F25C0DAC4668534B6647EC85454BE945E8 +26B26DE6E3C4584B97A38E2B40A0D23481BCA78084FE80E00A71A790BF31DF468A435ECC88E60A57 +860BBCA3D65930186E9917CBD209C230E8F8255A7ABC7D3F043AE4D7AD63D9980BEDF062B7D5C298 +C40225B6D03F29A0339E0FCA02138E526F06B9EF47F5E7A8068A846CFDE2BFDEBD24F5A73A66C079 +18662AEC80B43246284FA4E2EE0D9AAB172B1E59A6CC46B801149D8C0DF6DEC9A55D8E1B0EFD9D30 +2FF618075944CCCB6831D336B11617107B0530D09885E5CA11A5F1FCC8D69D603DA16BEA51116D42 +CAB1AA1E4D7B9B4D79993F2BFE53EAC904FEB70B2D330A89780EAC10D12CC0C35B8399F218AC2976 +E57A26BAD20CE2FA2AE2363D3FD2A8A971747556F2959DA74A8963C20B504711AE1CB0D0C02457FF +2E9BF696B159AF031DD5155F21C0F5549B0471A3C5DC8918B675CEBCB23E29322B959ABC05283A70 +2E878DE8EF25EA760F3C5C7B7B49D398283DE2ED837FD59F7C22D62C58FE4448B1049FDEBFC8787E +67D7DAFE9774979BB3802254DA59BCC0219F98C219F84D995CA768B8B5D9D4A32525DFECE003675E +E4BD5D8DFFC11025AF2B468F9207B5B2B42349B98232BAC0759758C1F4A283405815BD7145C93FA0 +8F3ED2826655053A3C2559073D8ACD199DEA2C5BA5F616A2E48548B4370EC73493BA07E197165DCA +774438B0766867819C1154D1959FE6E01E6312E0AB91FC2E2BD240FC8652A2D456A1DE7F34EF372A +53794D4C4E050BF3CA5B7BD2F1B8DE93B4C8002485CB219AD2D029739FD3C81CC6E78EDF38723576 +1A57143EEDE5CC887F282FECD261F6A25D0A7E154ECDF5DC38E426811BE86AAA458577E5E0C5F0F7 +5AAFA9C41E5D1DC9D91ECD79B514F8CDF7A5F1A189470D35FDF4F9B8788879CCBD91B427822ED658 +389E981E0EE5F7FB87692A3E3E931DF8A1D1573E3B0166204240B7080089A09EF7487C9AEE2D665F +5A82F94C877FB5B0DC531CEBF1E71C6592CEA2401E4B5122E5091DF03D203DF979B9A6EFBA12E2F6 +B422FDF15D49AC0914D372D21E871DE65CBECD105FD4A3E4714B9CCA5C6803FA39DBB015EA8A88BE +7913502E562E5B170B87BFC8572DC9DF49AD63694311EF1334444BDF0B4CA3245271C1F7A4D7FAF1 +703E3AA0E1EA8D5C6E821B28707EE0C9B4F22F23796FE87356C58AE2CADC191F4C58E1FB58DA03B4 +5A25AC95DBAE13A293474217BDB214742B9D9D6AF35F70FED2891942EACE3E625E55FFB820543FBB +250A062D3D395BC0F219ECFE0D76686AC148BC41476A887BC494DDBD396BE200FD3E03CFA12EC9AF +6B934A283C42AA05589AA6B4A8D16946BB51F50419CABECEAEC5AEF9085C9989289E9B46BAFB6FB2 +782D84DE2B068F91A9744AAB237CEB1BA513E57E4C307108E993C972A3E0A898D5A8D27833155031 +FDB98863C3BE7FEF3004CBAA5CB60A1F2E3EB4D7290FF5FAFA088B1CECCB6CF51A58DAAD998F0839 +6CDFD68F5ABC9C1CCB8F6514107773C69C26873E889D1F79D10E866910E4684186FCD71C965ADF62 +39BA3418B313A27AD632300969B6F284519366ED85E7CD968D64823F8C59B5911A72D0A20EB72B60 +3A61E36F52F256FFCDF706B4560B4DFA5D918FBC530D83A4B3C01BDD3CB4572E24242D141BF9E775 +36693A0407D002E09CDA5B195BF1CCF430AE9824C07928A050D0B460F2704BE8F9E647A4884C4567 +0A81EACF7CC038643EB0FF18A376FF6F32B6FE4F197273327FBBDEC6443A299CAD4B26F7778A99F6 +5A11BDE047153E764039EDB251936AA43DEE50DDFDF8856519056AAFC4C5AE6F2051AF0579A9ACD4 +1D00775D7DBE70022CC263DCA5E0A25B9C7C4F5C418587666B2FE24816B1E0EC92F9074F1403BB83 +AFC3F1D52CA79C387BDEF864366E34C90BE52F7AA09935373A07E4E026224E76F9EC3CB9E7EDE50D +EFDA48248D61F3CEC880A3B8843306375D9711E58645F3625BDB8E87052DA67F9794EF4AF8DB0BCF +E00677C3A26907DC651BC838C40EC39E2B5A5DC0DBD345944A6C32226089D63C52490FA10B215AE7 +03CFB663EB8A47793B84CE7364DA1C4E7FCE32DFEF09490121222774915BA59C78C2275F829D15CF +4D8686B095C38C731B83D48738C25F40B8ADD487C350A2EBE846C3916AE384CB1050F9F5DFE09FCB +D9129C6270FD86D55A459618FDFA4F907E6B4746196BB717865AB378414029017551161A52E9D24B +E4F7EED553A927933D4ABC8F25DF607779A717909CB4D810DE8F5762581900E224E4B91598149BA4 +71CF8068ABE8744356B261600BFCC57FB8BE45036CF6571D9B2A95304933BD4F17215F8EF53F8E08 +1AF61FA7F9583C34EB5655CB0ECB82246959F09091F36989EBDD646BEDCA614B9A61AB7696B3FF18 +1058A150FA6EC1BE2EBC7F64357A3FF2A2B0491D2F4E0B970DE5B7788B467CA678039B5EF55C88A3 +84578D427FD2CB16C87B0BF0A3D37CE8ED43E0F049AF2436344D5F47C948C632C94A287509282561 +6C64C5D262FE5B24916FFEE982A69A6CCF888BD01D62EA591EEC51F4B7DDFAFFBEEA93FE08D736C2 +0129E345D06B10246A5F57151C198D407730713F32299638EFBDC01367E23EB59AAD42A83AB41B43 +2DB462652E29813740F4680A5D4BD47B18328FAE6BDF4200CFA4CE3773809B45E8887C9B2E423698 +9F6C48D64F5986F563D9A7538A8716082F81936AEBD0461E6F4BD470436D8B7656F0FDF89108E6DD +02ABDEF907731D458D690BC608EA9CED09EB1E6E64C0790C7A2378201CE997FFE0317679EE1D4EE9 +F91157449323E53B4ADA8096CD628B5861BF794543A98F2FA2AB54FF0F25A13DAD43DAF9394329B9 +5AA53CA32749FECB0B2BC035DD1EBD53FF9FB5AD8BCE06CD89E5568091C1CC314CFB1D9821D7F9AC +7C55F55E0A16E39A87D43148201B928F3C42B110FC056189DEF183745F3B637441DE8BD4C3C7EF12 +F4258E306B2877ADAEC63441010750DB4E6269A4C78A0AC01BB3603C386651FE814031CB5D8C1F14 +9EEAFF652A53E57BBD4C8C0CE36A84A319A53BC1E5FD3F1ED1EE72F4C1A9BF264B594062FCAFB22C +C1FDE3F2E3D3C17DD3F7FE0E15EBD812D550227C06D01127385374A11438ABD50048E17255FCD2BB +85122A6FB9B7DA9D5E9DE8A747FAE0DA45A1FCEFE92B9E70A5B2CAC668D4D07527A5C1403267D823 +048BE671F725CFC7474B44FC5AAA348420B2D7C23C6CA066666FD6F2208E329878D90CEF1C2E77ED +22D3BEBB9D547810B189F08920A27E7107F208591A84D463CE2576C70C3DFE6643E4EA93F4E1DAEB +41D46F0E2F56FC10C69AD5034FC9859D31CF27A3A1EE256C93111F81C11ACF1FC0CE20B90BAC9AA3 +27A5C85A7985B951519FD4B03C40BE637162AF41B2FDA68F0D1E9B7602FE2659D3D75955C579AC51 +DF6A552EB9581AC3F712F083F19B52A6C4F560F36C59CEEB0C996AAF1728A2AA45DCAD79BD7B23AB +388D5B0B64A2B95154B6259B730B0F4A72C8C7F7CC93C7D64D9D8810D1F63FF8ABD4DB89824E2D26 +4FDEE916C41E299211DB1A53256E1DB5CDD04862F034D9404B73183A99D3D13D642A663F129B6D16 +7095BEB4EAEFD03DF2FF2F0B6B594C1EE90FDB203DA89FACEE23F1BA3901FECC75FE1811BD701259 +343011262B6A0A9707AAA6316BC3C17F787BB80AC8DA5AAC942D90F80C5A3BB59E47EC767244AA95 +C63E50BF809998957936D3BF6ABC24B0A397258F9EB4DC8F65692CB023D9091FB180C69498CD0C08 +BBEBADC84A7E0016E8F8BEA325D924EB0DF82E75D2CC2CCBF039B11934363D4332C5FBC5EC556BE8 +5EE4E707CC2753CCC43D2ED50558E51A104221C9323CDCB0199B7B83454DE3FDC810D0F362C0299F +5DD981B31D8E3DDA284FEF9DC8F9C8DE138D3065437A7FE8C30572AD06D62E8527AD37AE39AAB0B2 +25F76A25F6C6505241ED73BA494CF923E919F688DDEBF193E188F8C4C154F21631080763B4D091E8 +AD1D2FD6649E0CD9360E8D1A67A5B5FAFC67547CA31C95A5EA8D4EB5D68B9F6D6532DB9B54584735 +9558542A2AE58C09F3BD2918EFBE1699E9C8F2C2A11EA4D224C726D2ACD4A8D8ABAEDC6588CF2AE5 +66528B94F55B823A2A1F7BE19000F3E7579D094E047075DF18C8C868760295533B26EB3ED90635B1 +29C17ACA679C3E88B06998CE5A7A2544B700229F5A6A504BD3E45B276471959C8A3F81917A534287 +39B5EF9E3D463B3BA7318448E2A3E79520D2D245A2A72F31FF7070B6E4624E3A5E216BD103640C8D +F387E49D732529C611F8B971073F17EBD2F6EB18F9B74A67E1997926DF178D4C9EDED435B9682F1A +279C81BB9F60DAFE125845A2FF3B02979E5481C78A45C479BEFB9FEF3CE2BA9BC46C77B50B03E48D +A6D17B76F06F3AD118371ADC69E178C52B5FB4B261C9311874ED07DD6D5B3226A005FDD7A6D53848 +09E7063F036CDEA41619122635E835D2D74CBB6AA9B38CAA4D819C26E95115FE0DBAB4198FC5838F +2C91B7A87B07D734C6D4F4F83444C1E90AA9BFC908A2BAC4B3DEF9157AFCA5248F2DA31CA87BD363 +AC25E9E77F741D4B2C6E02F04987A6F49D30E9038CEFC41BA172DD675AED8B392164411144E5B738 +F3210B0E66B17A13CB9631C33D44484E792A7C082DD0A5382F34C5637653261B1EB6D2035B08B4D9 +1FA9AB770CAF40A103629511F7B43F2743D7E583433DECFB19C21FD4FD0AFCC22A4119E77C87BFE6 +FE50068B22479015BE5A9F06BEAB4D37412E062A45E0CBCD7BB39FEE747E96306F79FC4F2E8942DF +5D9DA0E55AACCDA547DA19D30B8404FA121298B44C9CCE198C708C69A8D6BF17591C5C50D3FC5BE6 +961F7ABA8F366DAE957A1C3730DA4A5B4F035A9274675EE3BBF0CA8CE9D8349F50CABB1C3EA4948A +BE6F9F143592F1EA95404E6909A909168E3279A957AE1924245C356331A75E7008BEE92BEAA304BA +40B7C3F48F74D9018B3247DF50EBD7CE541DA48ECCB1B0BE51A455C3C13C279D4D8676078C3EBE43 +08748D52C9B041D3E7244C745B1F2F742D010A9E60695F3EC4FDC1050AC082B905D6A57E8F407A3B +472F731011A5798965B7B1A307E252FE02C8F79CEEDDEB6E165F1A94D7FFF18DDBDF79477F14E9E9 +3981ABD200FE7771B29D1D2D120EE79D28B9543818527039AC74085EAFF241B56D08220C958B5D9C +87C0C04A14D52AFD475B542D391BC54FF33DEF8D9484AFF6873BEED32DDA4B371112B523B6CE22B4 +0D1B416B64C9370F1CDF2C548F4CCBE9E12E21C36CC3EA52DA232DCFB65F66B22B5E2EC04852510D +5E264EE939BB67AEC4764B87062AEB7F680B40BCEE04AD45C7519EB3B6199C9E0E332661463647F2 +FB7EDF303EFEF84891CEBCF0FAC5F723A9D0476C3F8C092604C87FC69C7A90F4D64AE45A478EE8BA +2DF50FB93F55A3546123F0B0E2C1C40C98EAAE9F0F26B8F80FFE6E6B94B7E27D2884D58B8A119662 +2DF6BE608C5569D7864BB756DF2EDD184B90812B44ED4A32D001C31383A40AEEE9743651F7950846 +15C48E402DBC01C818D477EAC0347795CB2792E9C11E8FD4A02E194EED1C919D4598FEC003B6D9A8 +A0BC7D456047A1C0579453FC1D7CB2D158D466939A23D7A7B8ABED7E2777EC7487973E73F2266D9C +250CE30729E3C5223AD93B9AE8443B35711E446A3DC660123ED45CE1942A1A2AD0610467E081CE2C +8B92A6C82F0B17B5D2429E99F1A6268072C6B5AAAA6EB6283A872C54D3694CD825EB2926E57DBBC7 +C1663075E687A144E4D61C225781D80FCAE1497B442342B4A3F1CD6BDB50E31791CC3928C30835FE +F845B6BE5E2D7E3F2F5F085AA3FAEB45CAD0D76BCBB1ED859A9CEBB9F7457036F0BC3F195CB1A98C +9C8648F6583CDBB23894BC719D68C2DBD8003B10D08C8CAA40BCE784D7BFB4EEC9EA5359AC056E57 +B8B0F2EBCB1F4CE40C87FC7861180133E0CB6CE2FC4FE690756D327A2B5AE063E3021C0C0BD420D0 +56F0B941E6B36088A55BA11D0C35FD0132D5F48E5D9673572347171B4328D4807B972831C0D74CFF +A5638C145B89C989E6EC942148207D6DB82257585958034D9F9D4221C7C9F7013790DBD130F277E0 +BC88BB179DD09E27062379ED06F25EEA8B7FB33C35861A0034776E3813D2E9E5C10E227CC569AB36 +CB2D9DF2E7B7B44758F9DC4FFAD7A24AC7E9F47AA850C221048C3CB35A37CE8EA75632AE65FE3212 +175146FECD6334AE3D3C5F492F067F795E1E8FF386BA198CB74F0BB4DC0000DA383BC4CC3F070DE1 +7721431988D69C8B1A5AFDCCC83C22E16A87E01C6D3E79DC7AFA3DB0371B0866EFB8B6F88900472A +FEF1C4A878243C52D4E02E82658979731C841C489A6B97E271C4C93800EC7D91F93EB9B9C659A554 +E1FCE42A5EC65AC39190EF4B66DEAF6FC0569A000A9E1495F42F706FBEA4D32EB7EF11A648910259 +6A65CF899C2F322F5679C6D123469192A9BF1A7F1F2C81C554ADB97BD19ADB746A4F81A4D5559E60 +AB94C483DBABF6CE2F28CDB412D50FF3FCFA3B3DAAACC6A83CFED910CCB3B8D2C19590AFF4D75303 +4A6CE7F4156896A13808E0DFEAC547E69D3C886691728E4A35ACD575B40D721E8FCC5385A2EB28D7 +08101DC50811529528F5CB0C009BA7E3C88468E37768FB0D83895AB54DB2DD5426562AF9D8AF304B +F6EDA54E9C92643DF926F5C3578269750120302A37CB140A18BA56BA01108D4ACACE8FEAE640A6C6 +958EF156B588ADB0EA5F3B0F37BBA12B7BCB221C811415387B024B7076FA4403A3AD6EBB5D9C26EF +EBDB7ADE7C60B444AB9F90EA493B658B7767AE2BE649BDBB3FE85F460F1ED137C61BD95F7CD3D8B0 +15CE45138538930AB62AA0E54B4CE1A5EC5FEC0A2B28B345B67089A4E4AE14D2E1F5A9C8848DA688 +CA298F93860649EC3AAFEF3E820D86988C8E3E5A4D4BB937791827994AA3E81D0BB3EE115EC36D5F +B9A392D09E79AF514D11C7B3A03C9F9C13355CE79E119A19177FFDCA34704D38118A8976D1EE5AA0 +2D14FEB1414419F5E85244ADC5C0A765A522EEF36170064BB19FEE3B5F7B441E4DB967DAE0BAC2C4 +8FC6A836E0EF5A69F073BEE1699F55E9C757EBD6FD8B514E2B49D6333815B7DBD1E0694695FCA3D2 +1320A0C4B852D9706DADD8369A95FDD917328BE93DD33818954DBD2C212D2CA81560ED5BC284EB04 +7A5F389E24E43F4FA8C97FECF46589FA7341076555CF55B1C21B28E0C1CBB00AB8B6F67472F27BC0 +D11148F407824B0159B5188D4BB7386FBDBF1C0FAF34721B7BCB5C0FCB7C4010DCB6A1284E9D7883 +9E3C2111A05D29AB7997073B590A81C6168020F1D48951BC7D8476D5BA593F4F23CAC1F9BB0E091E +84B4E99E5C584D1370DD12DEE8DF16AF8BC6B7B23E2FEABDB7F32779AF8E2B5094A6E9B7A7225F24 +C43A8E5D2B977E1E19E633C26771E23017ED233DBB02C64F8CF03992C6484528D0C8464B46F24F9E +8380F385D5D01B8893C67FC103498983CF939432AA380CA576D09030CD52FD99BDC3BE16C7204CDC +3365BF76294A83A1FC14A236F5FE5321904E779B13232A76F8FE521F425562678436359C2461BEA5 +AB27209541F557AE2AA60009C9CA0A9FC7898C14306CE35A50017BADEFDECBBF94EE2905220706DC +806409EF87DB1D73EAB0698AD2DB72CDCDB293E7FB13C94D9FC87E74502E6927A212F0D7D2F2D194 +64F7A66AC07872E18CB1DDE8F11835DCBC5C4EF039333FFFC0FC1456DAADE7DAE3EC2EE0D3415B0C +ABB69FC5006F4D14A4EE1A5CA99AD4D5E629C0DD1E0F097B5B93DE2DD001A8C418234C9C45E8C13D +1AE04E9466DAB8CF1ECB88A4E059C111A6468D2DABB90DA79C7C79E94DB28F6968B1A632F8C57D9E +565FF91C6916026FFAC0661856B9FB8DE9C81661816221B1FC159CFEF1751E7E403F5F2CE32529DD +540792FC17A12A3DCD7C50D38EEAADBD10ADBF5D8A82442AA900CE6150EB7A4639DD9FB6E385B2FD +093493DCCD9014B23EB172E21AA89643A6CAD1093343D85D81261972DE0ACB16A4C6B5F0BE4C978B +FA12D3CAF0134F9EA49F6E9687C8F99A456745EA252F0BA9968C7F9586E3DD841AA92DC7705BDD68 +2DAE41518A09DF0E209F321D7FA3417202F4BA76A984DA3ADDBC58136885362F02F0A24EBC439B3D +BBDACFFD8498EBD29F88F016B1FEABC10785438EAC860B554525F3266097A675299AA0967BD3B7A0 +EEEE3FC578D1BE99D3533BD91571AED904BFC9DA1A1451FDC5406E1CD614E0C7FBC733563CD6CE6C +C31E9237CA153F1F0411114361D731636BCF98555ABF12848AD109371A42B63675A4130B81E97C2A +2EE2BB5D8FAE2640156001AF0F55D9D5DF8FF23C8AEFE14F120000F14149A36E5C94CD9081DEC277 +C2C34870D05011F99D48B0875A5FF542F067F7E9880109F586BCF2B50522A1F23ECE44349E539E70 +F84E207DC9BEC7CDF856A046F1A03226AA41F541719AD1AF88FF211E57DD0C1275DD0B7B47440DA0 +89B98C6EE92A7D94700B83CEBE19EAEDD8A615F6587587BA8BBA3CE3AA5E8EAFB1FB0F486BE3609B +169EFB178A4292F4C0378AFE5D24EED1CAAB514DDC66C696D8E37F294A6579131DDF5488E9436609 +ACD750C3DB0A940C84FE022B22ADC2676F62E91E8F891225F891FBA537679B24547BBBF35F04915D +20B11739F620D18B5B216921D222F15044368569AA302980B9225BB839F494588481B94B0C724352 +B2DF600A22B062561D86CB8F81514FBDAA4F8A043A0265F992FAB71FC9124A45B8475E1EF3DF6B6D +E35CF329777D45F08325E8505EC0D979F542807AE77E57E453525F23BC59A50740371EFA98678AEE +6C425374AEB745B99DDB5D8D908FDB551FBC0DB15832107BBECC4E11A1A8DEC69358A574A2ED46CC +31D564549EFF23102D92BFDCBB2BB985F78F36033E34F59C0EBAFA3BDD71338736464CEFDBA91398 +33995EDA4207BFD4A9867D32E867FBEB7DE60D132803EF9347CB17BD91315484EF6570892297DD8B +7D966103339535E28A00CB1EECA4A9775F60A9F5FC9BD8B06D78FE8E6318C31DA2E847E3F9CA587C +B01AE2BA0A2EBDE308314413F4F230A758184ED60D4F71F6CEC22A93A01B6C54E0449A3860FCA895 +4A347B7588329A80974ECBECDA1070FBC055666375229F13DD995E99265DF870BC8B8CC6347FADBC +1A6AF64599271A475B9123493D46BEC41289BEEB67EB97A8DED7A9C9730D37C65164CFBDC22E5CA5 +89D2E7954C7136EF4E084C43A6C7F361A3E96989239BDDB9A593CC2A80BA16DE9EE90E95CD39393C +212AB22EECB677FD36D34DEB46C4AD0D21BF7E6D7CBD0C8083842FCD87B18FEA7CECF939987E99BA +34C214E44DD84C176C9CC5A4CEA76D380CB316BB4EF9DE73D73B4AFD4ADB54451591DEF86621D138 +D5A0A29441502BF6C2ADE671CEC3CB5CAB903A657EB2D70C943F976C110E46C5D9D29BC00A875F27 +38E5D22496A43E096E009C5D3CB724B4CABB32838DBE527F83B18CB457E57B092C302EE557FD4F00 +DB9C56E66C9FDF4EC9FFAAB85F60D02BA79694FABA476A199A0331C30A78A92E10417BA236E23364 +8174C826331DC1BAB87C5F95027846130C6A2B4027930EBF9A97BA1B039D386FC51C302648E25980 +212F6A582CDE2778C677A01FBFB3C5D1B8A374ADAF6ADBF7DC94075F25ED66D440B3922C5F255FB2 +3FD8F6E21EA65B1D93BB225684B50F11310E242B087575973345B229BA62C1E2C35BDAEC04D10148 +F5B2F3BCF7399BDFDF1F3F79119714AEA697245BC647316EA157484ECB951BE367234FD02E8B1F09 +1AAC3D29BF282DFF4011BC0CBA8E55234D943DB3017CC7A766720BBC29B2D097A956C0F1067177F0 +12D42ADCB473CDE8D1BA35B4030757FA1D8211989DF3BD22CE5D501C21EF8708FB3449DF47D88650 +9FF7B59B76C0DBAE443F336FEE2D615D7EED1C284F14335BC8A26BF4621E10DE9611FB2F1DBD52E4 +B7565D8C65B54EA36D508BCF0C578A49A2665227CDE1F9768EFE847F9D94F1BBB7DB83701C232198 +5C7283D47B2E40B27A268428AAEFE75F6B2F8764A8494E5827573758CB9CA46FA93208836BCCC8B5 +564A69F5AD882052AF1C1417C3FA7F580569528682C77080F3688B65E7FC24D2A3AEB61574B4A321 +5927281544DDD7A6EE0A3E9388F8F631CE7251724DF70726E5912DDCCC8C652DD6C9608F8462303D +867F589DE0F2F71711B35142EE6EF93B64D6326C4DD7DC83278E057100EE772082E6BA368ED91A55 +53ECFE2293A481E42F83BC8F9148C70EACE91F7B7D9CB8A72415BDB3AF66F68EA733A17ABE9DB005 +3BF148629132969589F38D30EABFA96A01FAC72650B5A6FF3935670198A1EA33810A9B11E330EB8B +451F24F93544263436F669AB5A90A53B16CCEEAC36B1445574EFA7E802DE73522BE725E68704822C +B7D3912717333367895BBFBE06966A5CC653AAB5E9B3596702086BF0010085B900711932A95ACF15 +CA4DC45A754EA334E9EB84D6FC8E3FC4F897456BED64BB93B593549FF0D5352275D8E417172A6664 +C5E0ECED1019494A7ED49AB0B965BEC1A82E5873766BB38D7D856049CCE2FCA65AAF61E961B60634 +E2A69EF059754C9D8163D87F928C222772D070D83FEC6FA5AC734AF65E40BFDE521F7D9CB1650FDF +64754BFF21EA3FF0AF7611A93D525EC9B28C51AFECB04E7FC8323DD6C9B0D8539A34FC3CD8CEB795 +8E8EBBFED4313C77ED469C199552A9FF70BA5423B03B6148D4EAAE17B71C5B39DC436AC53D6BA8A7 +AD81AA8B02335A8B2B11E9F4FA913159A725B8AB60F52F1A2EA50EAF4D56656E615BF382CC68A690 +BF83DFF24FE986570ADC0290ED1A37C1C2AD469CE789E0EA0BB5CE01020100E729721AF3B5BADD33 +A2DAA6C33EB8F9064F5292F715F820B4BBFDD56F76D42E7A1A068C1CBDCE4640082F6E7D582D1939 +990CE6EE8D270015A2C461798B37DCB5798EE9F7512168B76D26C28BE4A49A1BF96C89D235F21A1D +B6A96E5DA474D0B19B808D13D7A11BF39EA8647499C410ED9894A1ADF33D41B6FC2E614D8087F4C8 +4E437B136F3CB32DB8393C49177A0675A0C9E7EECEF448A97AFDBE840FA01FC7E5F2E8FECEDC1884 +84C312E8635CD79195475DDBFDD4D38D5A0246DE2C7F21608F8D2C0DA1371D302E941572E5792A3C +F4E51A33228B93A814D03FD4FC223C314CF3714BB3A34BD4F7ED6348577FEED9DEB082C4049E57B5 +D3CDB7F26629E9F3BA36893E09E3C7463D02A22D7056BE76B87763260E46E48BB832B7EE13F8DC05 +37EC8E81E9BDFEAD8C27EBDF1AD706933EFD11131E12814F236EBB01BE85B7F1B2D627413B324918 +D247604F56EC128909873FEC3857028BEF76A3494364C2A7002D104D486236C30B48E2B75D851C34 +EA50BA7FFEB4E19190898AE21768C157C0CAC628A2181A32796FBC1A7271D2473CD88E5395DDBDB1 +FC3AA8DF0F3D588637F19A8B833AFDEB5F655A8838EECD684E2315B72C75CEEFBCEF94344ACE8D6A +DBE355008EC72FE7CEEAB01363A895F4E73F867639BE0A0BE67333848816B05B419221BE8F9066C3 +62C23FE85B7F392930BFE4C12B9526FF2FDEC38F23A159ED61A0718E7115C24597D849FA76369153 +54A40C965D4D72EC94DA61A03766AB39AAB684E134FD1407A5B1B19BFEBA52AA0DA5D99CBE5C82DB +AA663711E6DEBA180E1D4A39C320516A4350D296BC19BF1BE054859A0889C7E9727A021F3176FE62 +0FB0C837E4141FECE531A950C03D319E3255703220B7185BD20FE5DBA673F8129AB211EFCF36EE39 +4C7E00EB0876624BC840FA86E58B2F584754CB6BFDFD76810E300741EBE4544E5AC17413ADEB21C6 +2F66CA4F075C32381796BA709782DE34A675B717A2C7F6D88104CB924FDE5DF775B4F0B68E0E2E5C +2F788BBDEAF06D8E1FC2105CCBBD5827C0B03FD6CD64F0D073F3192D5F94839644E5EC6C5185BADC +F04112A65F49A8C83174A9AE958E76A2F5AF469E8B76C833782C5FFB8BD7B1BBBB3EA0CB7C9786C3 +BE2ADE5E7AFA8C8F20892659A59BC421E28845A108E34EE17864042EF587A6D67DECDFB3F510EB40 +D2229585347A0035670FCC76C2837A4E4D68304FE113C539B35C1F0234B5079B8E32934546982978 +C5E4DF955A454EA263C3CA5D7101F31A318D82A3F9FCB5A8AFD7A65209663B0FC9DA400B26F285EF +46D0E1EAF8ACB1F1CB805E3986D04BC585073FC64895E4DAE1CCB749BB439CB32EA91176D5C39C36 +50D10AFB9C9884D5FB90183424CEE67EF2175D01D2478D67511EC9F54F88763C152697B06D948BED +49240096EEE3D06AB4575E8E8B2CB8263B5BCF4FA1608720F52B675309833071879DF52C3EC2871D +20F398B5CAC8F8A4D41D0F1D47584DD90DCDAEA4A1CF160C4B3BF1AAB890B5CEB6CB3488672AA68F +BD938281DBC1D8BCFE92FBF514DA5358443CB6E0147254E91B38CE6787B2BB0DEDD2D38F5938737A +977B5EA42892520C58F8FBB53C994B57382379E9490F0D6970B980E1BDF8CF9F4C3C5E0A18F66E86 +EE93FFE7FE546DE50F41364BCB3721B637072571FA1779F1D672FAD260C16D7F13CBDF3E4376E7FF +56D2A710AC5AC35FCBDBCE2C9C17E523BBE6218617B13C1FA6679B308979AE7C61DA6E68369324C6 +CBC7DDEC364E5A86707266C0B459EE7B2C03FE584E529BFFDCE98C90A2F3D9305AA74D3ED8430DBF +3A49FE2ECFD9C4BC9FEFD22618FE9C8A973AD072AB6F713E4DF02DCDA7AC5359B2D652013E131B76 +B3ED6C75FD53BA58D862846264627F6B9E70D8800F6D9B32242B747A67BB2B45675840D34F852AA8 +062FA6B01E31ED24DAE02F6CF788A17F7B9368175195DB0072259CCE0FFB2C1035C1D26E1777CCA3 +D56A827C3242069E76D6DD69B653768614B9ACFF16567FEA61508D51454BC02F6C60F755AEF6AFAE +3536BBFA1823F8E1A53C41124DE983E51CEC92AEF4F99785D554488A51C20885346D1F761DA79017 +940A0C557D93F1DB6B3D00FFD61D08E96FF3AFCE5FEDF545CC9F47A2B1BB26713431D6D1E47FD6BD +6E3C668B0368241F0EBB5FA9C991DF79890E52E83A3675EE699B61BAF869DE91F67278F510061C6F +E41DE2D883F48CD0E068E2A652B244128D82E5CD52F35F210DDAE3054691ED55A7D99088AAE8FB04 +F525C2084AC09F5EDF80A4EFAFE981F74C0DE9D194320709B3464F3FF2C0F6AAEA6D973D9C323F53 +DE3D741F698FBF01036716BBD62957CB32CD81D3A2674560FFBC5BDC5C6E4F547E589AD0B1CFE14F +5E17FED1C4A8ABE4E67CCF8A49F32C4C6044F1431E1CC382E7758722A6D0DF9ED23E51F8AD14D11D +7B6428E27443715EBA4E9C05D6F238378F9498AEF0E7EE4FE6856622CC8E6ED141EE5F109E343CB6 +695C4BE1E0F66601C27975983BF557C04ACFC19227A1AD7E6C44C00529FC7EDD7F886D24B7E029B9 +C395260088BBFB96972199A7B32796D27257DE83A7402291C14FECDF7998C5C96B1EDADE0280F856 +8A8F5007852EED303969180B3329917973C2D32C080C9765B6BAB0673BC7ECFDBBFBEA980C263843 +39B7F1052591D91667D4FEE413AFC23DE2D4B9DA742F4269C6C939F5FC32A38040730A018155AD73 +3F231E4D5B9D01C03A58EAE7B5F590CCFAF25EDC8552CFC8D95C60EBAE1837D7A97CA137E9D4A4BD +2CD34AEFD68D64B3F4F62326AC429921D7FB3C235184FE0899690A0B775F1A566EC29D5830D32372 +6526F7E7F5AFDD71B77E07613DDC4FC63EDF49051AEB59E6337AC0A4B6DD872E776C9CD0CCB86130 +5322D816732124F5978A86C186BF0A0F88E733CE38E4D7C1BA5378C5629B1EFC97806059990ED42C +5CD183BAD7E94070E4058569DA2E51831FFE0D080301AEAB4350BA290318AEC582C78D05DD92E5AF +B4424EA808629BC972E68F4FF2489C245593F07555CA6A2B25964794CF31CBD3AE5C229AB9B8C298 +06C01D116EBD0FF0F159ED2D3D7DFC73EAB4910BFF5B0B0B587CD9EA6E6FC45D63C09766224D8346 +1F0588140B258B1729F70BAE7962189B1554483392988CF230AF4077193E53330519394DD99BA135 +6D4730AB221DC6A66019BFAE564893DDAD7B177DADD16ADD21D396CFA6C3DC818052E2F71149FD59 +4A16DE0C2FFDD366C99B486C55A6E991E4D22CCB15843F0C3363676AF2F5B2D1B7EF66CCF2F12DC5 +0D63776BFFB058D70A9C76DCE96C754872D72C82A0C33F90D49C935402CDD26B6D743B1F43BED5D8 +B539424849C1495DAE73044E885A7D0F307F1816DF6244A6F2D97BFD4E200E93F69B08AF39EA21E6 +E347A47CEEBF803F73B978ADBFCF056789BB8E6E2563DE87DD9A8C877157B934102DCEDAC54D487A +1BB2694F0034093C48F10A17D32E2BDD0C723CAF59ADDD1BE373AF8C9BEB4415AA5AF36310C31F24 +354A53C0B962573148BEF91D994FE3F3D8450DD4D686725799F53C373A0A3E3C060C2E1A3E800504 +9F26D716E1F381B9F83125E4683264A07E2D8938F605978E2513DD2050B3D8A1012797CBA8961632 +BED260916338A812AE751C7B657E086A0C7DDCD3BFDDFF3E48B84751925736D1310C4910FC114387 +F3ED7FE163F91895EBF55FCB425CEF5729D99BD8F2C072E36C310523E75CD8E5DE49C031C4263410 +9D56E91A46C8C8E89FD92012A00C33D0DEC52597B5C6933291A7BDC5CEDA95DCDA5600F9AE1C8250 +54E7EE1067458CCB66610704C58E4A4FC0CB5FC933D0322A716B2CD430A3AD48DAB3D4CBE9D23F2D +092368CFC4E1F5495C133A92942EC62118D45C17723646E69407B4A89DCDFD2AB3FFC099A21D9D29 +741D68270629AA3A414FE58658DC9170C247B6E23F35C4BC5FF83009F462F2EEF4DBAC5FD158A658 +57F9B6DC1F5192DFB169DCB65621CAB2F1B07BD22F4155A8E9E2B6388D430FDE5EC1C834D22EA035 +C52E1E34482EADC36B4CAE902AAE89A7284E62B3C84B608D6BD05F75BC31310B2DD3B2C08A00E073 +7F104F03A41989D5F6B9A2C38B22F1D1803EE5D7A4D8DE44E4ABD496A1DE0C0E12C4BC96D0122846 +3F0EA9CE9509FEE987139F3DD3F9D0DF4313F555BE85433718F6D05F197C41A9D9C7A8B0D2740196 +82D49F58DD5F66B12A6520D9F226D1DF1F1B65CDFA261F980CA25A92645B86B64606293F8BFDE364 +C47D2AF2C709BBE77A70A5712F2CC26F3D66F5BE2C307A48E6F887F681D30121E32BBD87271B5DC4 +615D28C309F15AD263FB37424E56DDA6E17B998B45BE6C7FC6C28E3394A8764C9EB2DF5C06626593 +B5C665D550D4600172791CD208AE9F37BC082B0B242B0A504B751B18F4D7495172B697EE217834A8 +A4FB7CC16D6F9E8BB400BE8AEB0850960283DCE725249FCC4DE97D9886745AB6066C3E2F64DD8AB7 +9AA11667F11188D7965DC11EB760B772E282DBF13249F31986AC6898FEBFE23E3E8B8D2C33E00EA6 +FC493850ECB2E6D831D1EFCA3C2EC8EE2E394599091ED58BEDE97D7A43B6F739EB0F845EAC1DF6B1 +EBFE876009CC5D804B15ED4B56761B3CE1AF59C07B49DC798A44532297AD73D5101ED47F36A3678F +818297CC27F6AAA2AACCC9AA9B6F5459911D8C56CF499E390AE607F3790450B2B9C9BE0F006EDA0C +715B5CA0481734CFB0597478E7602B0D2C1E4F78F03C68C17C70E4B42D7D2D3C95CF40F73488B371 +8E2CB05A549944D86944D78724E266C3319AF89AE430E777E95F0D792B1C654306E421F3D63A26B2 +1E74B6E8B21B2E2B9DC596D013CDA16D08E65E8F24A84B12B2BADC653E6E1110DE2E709C1C1BED13 +707B70A421B384F20CA7A9A9D20324DD383F28B2D3C7A9C53F5D4C6B7C378D26DF11CF55238BE1B2 +4FA70DCC178DAD3D35670FE4919085EB1CD905971D76A368FDFCF9D2F0A23739851A3A6D2E02D65D +54DEE69ED5D81315D3EA5E356F94EF256DD267FD1E1A9EDC9CD63E743F299BCC4A4506233B8DD765 +2CA067F741603F93250C087D368F9E9CC4CC1A6DED567487C05BAA992B0056A77F630A72008E3946 +15A9DB24FE56A956650EC9DE90A6C2259189440247970541CA198748928215C0E132A81AA13208D8 +63C1FE817F70CA573B54577D10B73100AF8EA088208A44FB92ACA314AE5879706180788C17BB1D0B +81B6B95A1C4E0F9EA66F9B39BFE12444A6446691A7BDB03E0F03D9F07A10A7598F2166F108529F34 +CD90E601FFED3479ABCFCBDE8F051C348E48C61D95B00C59EA1287423F05666C3D36288844067E83 +E14F6B5210842C742B89F13ACD126B9FC50ABE2CA7D7ED513D43B6AC7F41EEDA416BFFFCC5C844AB +2D23D4DC09B2D510504CE98D02E72020D9E669DDAA344C63A1B75632F912A1C0DA3885DA4AF7E243 +E4A4C6493D6595BB6D56B0359106957259E59E336BAAF35BD1CEC5CDE735272EBCCAE8D4904AEBD2 +B32610C6FEA2B69941D6542ECB44D71092A3CF067708A3D087AE99FF29671AB7DD8758759B971A08 +AE1BAD78270D2FBEE37AA2DCB119D72F6C7B0C8509018A70D0B0BE2C6830EF8E0B24B1CE1141EF87 +3A4D7DCC501F808BFD94E4DC0F2915AA023076BCC8006490A43685EA25AAFC187302EBDE7FE1965A +04A5A398985D29F08E085127B56B057334D88EB638A4DDE64AFD204974C3939536B1B66A54B4DB81 +151853915718F70813F096CC1B0EA25E363B49264C2AD17158A4489F91453FBEDBDE15D7B74D7F98 +E81DF23251785D58295BA297F295AA6248A912CDD4F1111E6B628EECBB5139709E76EA4AB743CEC8 +26621D08E6BC64691CC90B3C3C1778931A28D3D5B1E20E96C643316613FC487C9B604C43463FA453 +3BCA1236286E6F5A6EEB2F1D9C34BDDE4595495A365F88055D9268541CF1654ACF478D384A5496A8 +772EA1402751A093582A6625A0A44816B5FDBE166835D598644296249B92CC90AA3FD6445C9A19BF +27F59CB0616C7306070F33C7DF4E1DE64AC8C5BB2FFAC1EF2B1B30E5A0275E6004CF64BBE2C6710E +DCFC3AA4ADD60106334708862FFA6652825BC84842736E47AE6917180365C75B27505EED3C6108E9 +898A780E20C3F606A860229AC46D0471ACA0187D6D539A1B8820F620F72B41AD1D3BF3834BF48CA2 +AFEA8BF535AF74C4562DEADCB63D2F5C7585722B77C989342D190FF926C8A5263B4F25286F99CF6F +C62EE6E2AD61C82B29D82468AC10FD27764278E5558CE8B41BA111CB2F040914451A480C93084237 +CAC8F66BB7C6689F340B8ABF0150E06D5B1177278A4C08742FE22F42C28680F190900344ADFA486D +59718C25D37275BCE4DF981AAC35D2C7E85C72A0188B8953CFA516FD545AEE0BF4B8BA301CFDE214 +4241FBDF3D204E3D2823301572E23F204C97305A82401660E12926EE7BA6EA1A81FF5C007933AFC7 +3266FAC4C134ED818A48E7DA01C71A46335C845F9DA5E960B25339D551582B375814148D94CFB781 +FC56093827B78578A73D4FF67B6B87F40CFA5E3F4325D9108CDB64BD06427B88C84105187316FA29 +90B4E3E8EDB6C78ABF164F4A9717D523794B2FE772A04DABBE688CCA977090979B5F47CEB90A1DBC +167D305EAB231C9F4260C4AD10889CB785169902FC0BED78DA15B8417453BB65856EA0BEA5245BA0 +573F623D215F6C0CF801851C305B355D26B52B0B343645FE25C78A3526841EDA480919A1BBE5F56F +C10ABEAA3E1FCCA7C43EE560F067F1AA2AFD642F769D1ACE8E2AAAF38850F0D757CD808C921D716E +96FBC07DA7860DFA70CEAE2888C0ED3CBF9586443532B68DAED9A926655C157A416C383A53D8F283 +2A4E67468112A09ADC837ED8EC95F70852921F50D4417239FC42EE3624CA97F682745CC5E76CC7C6 +7BD99F2180F8C0B7FB49539C8CC474C25C0DDE491671FF329E51BCFA779346D4686835A3AD6633FC +B5E0F67E0CA9CED8F215BEF4D240453EB2EDD6ADB22278AA5B985FA140C9834D38753DF2014F8C0E +E6DAD19E8FC54C03C1F6CB0F858986691D99592562CAD95FA0A5B2ABE4A8B54B457D42E8C33A2D19 +51C0419A72FB94FDA78ECD92BD2A1416459E9DECA9469F35E4C47DB531726DEE8F203D7042EDB32F +025DF3D582547BB1D45F7A5B70D317DF4EBB16E36B0D798E0932FD2A85B04FD67143E4B287A50416 +2C1F5A037CCD780088C5476385AF8168E12D97D44B0630621759173C8F1E3006B5B1C6D7138B7EEF +C3CC5F54E24B2C3CA7B41AACFD25E554880AAF406EA4C3C6E21D3B550B040FB1952598A7E8E6488F +E38288B2AEB6C4718338598A2BFE4D2B9D14C65732DA304C16FF3E1F8F03046EF095B65FD609DA87 +EC24A69278BFE65C905CD0329F6A486B8525B7EEA4F7AE56C2633CD83543269E8ACD6D71F500D82F +DFBDE7F7F7B1AEE67328549232E26CA55085B6E84D9E2E7F74068F93A90C4654F2F396E57C5F76F7 +E61CBBE523DBFBA6E76638BBA3064DA025A79E3A294FE7F1CC28A3B4C57DD6FDC48E541A85534B25 +E1BC11B4F78019457239EAEFD4BE9007D205F1D985F389DB22400B279C10948551A6B4A17FBDA0FF +C9428B18B43DC76EFB15FC2182216F1B60B4E344A03AD6C00F141EF99F89F24C819C3E32877A927D +84C2D006940F39CA8B71E5951673EA9BFD1749923219DE38929ECAA9CE43B06CFA7DA1BBEDFDA56C +61FF6C24F40E59B13870D5FDEB82D981154FAE5D6D5152DE69339359461A41A9713B6BBE47E868C9 +33CD74C75DB71D13BAE4DEC85E02FAA14EAD6C0A253B16C79514657B15E68CCFF9EE6AA385CFF9E2 +C53D9AE40F85C793E4E8FF50B2B7420F4FE69807BC5F37C3E300E6B3C3549D1D3246A2E70F091054 +1135BDF805E0A698E236B6496702D061241687B7B8D1A0E517DF0476DA09D89667A7AB375FD2672D +CBAB8124E511502DDBD08BA04D941DF1CEBDCCF7ED48405CBCC33774A68C5212FC6F132641FF413C +984F8B43BDFD7B1A2A3435F15AF07EF4970D3E4A0BB947C181E9CA27CC14A35BD1BD096875B45873 +8CA244F88C28728B74E25CB8C4FC1095A56CA75E4569AD3082EF194ADD11350DB3B74B96761D4538 +596FF7243B1E1B724716A144106E080D42036444FD472998460CE9ABBD05B42AF9389AC452BDBBA3 +A13A96890025789F16B9D92251FD3B3BEB2C61EDDB370A20456E3BFE5F4039E2557C451C524F8087 +015BAF3FF05F51869FB97512968BDB2B49589C1C7AF1E085250A47657465F480B7023E24C76731AC +0EAB6704123D77977D3A2C4C56B691346EBE589C619C04515D34F81FC6A17527D5D8319013C5D4FF +27CC3925E24C99231AC7FB9EAF0BBA482D3B75807AC85D03CD09DE5D9AE0B07B7A813F0449786500 +0AE8A7E00080300F0AB8C399057EDDBA273DD2E1B2A0DCEFAD3B332E6D4AC1FFAD846167DFD70E03 +46DAF84AF292D4F424256ED5AC4E104F80697050D50844A708EAC9E7F7784FD01646F3BD0C595CA5 +1EE6BD607D254E78ADDC5E15C3B6AC4940EC865A5C23105B6BE09EA09F2C05D6D76960A843B81EE4 +33977FAAC3CBDA85CDD2F4DB7C28293A77825635992AF8F3B38B4480D9A139B1662345A8ABE1634A +77496C3F57597D2985E9E54717AB2E99CA35789441BCDDEDE9A9E2106B401D9684ADBEFE40D607F0 +75C179E9CC03E59E65430DB70B441D43DF03F2AA6FF06F224B6E455B01C64FB89EEC9103E48453A9 +749B4D602808C7E408A8903091D85E06AAF635D0D529C3CDD1B8479AC0F4208C284BB678A547F2BD +77BB17C86D4560434F7AD1937760A6AA55B614CFA9FF8C9C96561AE6C8F2121C4E20237428BC51DF +2099B6C49E3EFA18E6D439E6E6981E746EBB1DC461259D8EA0F8099C47CCA27B2D982B72C9A07CF2 +1B3C05D6E26E6E286E348B8944078E24809F9C5F3D014B4CBA02533F5621BFBA1F0EDB776C634746 +703C9F73BA89B1960A496420C68F54E5B901A6D733D7ACC79F275FFFB253F389AA480084468BB34D +A1E797E43B7F6E8CAF5E8C93069A3A2730E57EC39B677BB73E3F07C2055599F7062E53B37A5F0099 +907D2ED87FF7A82C95FBAEB888033BDFD67BA3A6031A4CDC56CB1E4CF5B06B46E16D988BECCEFACB +9E1C037023D7BF5CCF5D65AA66A17AB361BE7981F132A578F3ABFB97960A6034F052D9D5AFDC0679 +782EC90F240F943A5F9A3D969ED7399254FF67D89DF668F7C56FCEA1FFDCF20481474AC8495D3AF4 +B6D7EE093E369C057F0B70858220693B398ACF8E8143558132E4391405E30A73937C53402E459F4A +A3539CF7A99A3F51C0307D045DF8B77757E92EA2F51BF0BB4F77D3904DD355665870C2B59F1ED7F8 +4FC71FDD7F0B6C5D3182DB77827CA6A2060D2B8C83C4EA4A432EF43A4D0A952CC6CBBE52A9F0CD66 +1A538973DE41FFE9C5CF55F2506B9EFEE51FBAE5E63BDCF5528499A47C031163C88D3022606784DE +2F46A9C9235AEE3D4F71D4959B0CFDC5B7E78C8C0A8F9DC99440C2263DBACB343C5C648577F5610B +50EAB1CF7FD02419EF3941C7CA0B0E64EBAD4B2CB05A0793DBC38F1946D44767BD287F5E9779C611 +CA0DAAA1E7393DBE0683C8D3455CDFEBC0E64B54B737E298DDA605227C0C4BBA87AA3EC7FA6EBAEC +39E6EF2537D5974391D31739D9FC42983D81AEE44711C823F35F8E2321AC74943871739D2DBE9748 +FE68592263E7713F27E0D49B9B5CB7A4E55DE54E6B800D15856450FFD3AE5F287B12AE4F438B20AE +9E27E6CAA00F3EAEADBE08432684FDF9931E925544A680182602A3C1997DE5D0630BD5A010535E66 +E1C123013D23966B3545C7431C39B97295BFA4099D14461004C42C85095EEACB9B47C593BC6DB863 +533A8619BAE09095DE8ECA432D4DDD49AA600D277E75DC3F5C6631E2A05382CB007825FADB77438D +CFA78E252D79B6A196D5164C2FEB85D75ECA25FF80B1D97FE10E87960CA0FC47C41D3A213BF141B4 +8BC3AAA93FA86245064668394665BFD52D12C3BE4CE39EFD8111754398A944C3FD1AFA98EC337BAA +AF899D35E804CF416AD7FE45FFF13FC6354007501043F98FE8428DE8013901BA6A28711A2CA85A27 +0BB135B72F1D5026E8217581860729E94F2F1878A0E96C59E9F62714FB5F8F25003DFC7347E99007 +8A9A331CB3A6A535BC61866F02513DEB982C4A13ADBFBAC3FF70A7335F40D5489E48E5EDEDEF1619 +1973D932479C62183B0E25EE8C4F76D4F1AE45DAEA4A12AEDD9EF81D248E8D19F8C8A5BECDD1EA1E +98783EB7A38149170851B1942C96C53DE06DEF80913BFC04E539EC67C110498D15B78268853E5C72 +F485F8A27B768569E54241F6115875E2973292CF48FF91D45EBED627AE9F0766D22201B20AFDD40E +5B17CF337F2999E0BD15B86E46EB3C18FC12B7DCADCF9DD50C6C7E3F37E615A892DB3F57E250A072 +A49F7277DD6A2C8042698233D35A699B17ECA5DBDA6D250ED4A16FCC893BF0DC2E33FB1EBD7DEDEA +3C1C39603C8B7E1A5A833A8FCDD5570BD088749BB232615366687962C7E56ED089CD7B092505CAFA +5A80F503C4CF337F07ADF0D106937E25670839D491F7BFF7A523DB609D126328C16113ECBCBF9C40 +04904427A108618AE5D4ED809F8CCAF72251104C94EC5BEE21F91B179D31DBA79CEEE5EC7FF698EB +84AB1D2D1A624F58B3622A78844CE51498B2CEF38EAFE259D22C7BA61104651A862008BC1DDDA58C +C45F663EB26428DAA85E7785363A69D2790996EF5D9621D53042F42F794962FEA46E46F37B8AD1FB +76FC8D5CF2146843F8CC625139C75FB42DDA71A752BAC48F294E4C0C8289FC46DA5EFD9C91BDA6D0 +27518B7E81E8B21F755A9615627D5812ACA674D1527A1185EED4E3C628196E7D0759B1CAE6B9B7E9 +01E9599A65230F1EE469CD33B9BD9C104C44E3C1AB966C9678BD0AD78111A4E0F2D07A01A038CEDE +7036D0534D684A1562A17AD64A00F279200C0371B1CBA61747671D2A21D3F9646CA290F6B82418A9 +6FA177C6278277504B7FBA936325F5FA124AB018A15DC18D2C5E8F93CDEEA52BEEDB78A57828D81A +3E6C38B9FAF3DC4EB7273ECE3EA4482A1C6242A335862C2C3717F9C9ED95F77B140C4E1569B2192F +C7DCF702D0BC9A50428EC406F8BD0CAF886B4D979320D3E429816D88F7C7146D960AC12E70F2CB7A +9F4E3E366665AB3F1B4B6440F55EEA26DC9EE0096BB7763731740A537766490C8C174723BF0EB40C +53701AAD12B21D436ADCE22203C1053A9DC4E9F17AE617888C4B4E6F3A720E4E6366BA628221A387 +D8AB15E04AD69387C310D3528BD2FAA5B22BFF3FA494F5FBFAC4F771C9C7402B95580C5AC4BB3AF6 +92A70CB2C851FA5CF1173EEC3EC29B5A05A0B728BBBB51D3B7AD8B0AF17A1563E82FAFD93F8B7118 +1FB7AFE352874F4EC6D334AB6747519AB8E847B7BCED33EB5458A828E074E74BA621BDCD03FEA604 +7F7B6ABDA01FC7514BA1AFF0D4D0C0CB8F4E42D5A87E395D9ACDD02CCC220C157153422018725846 +009A3ACD8C8CDDB66BC6836B4026FD9F526AA275D06C813179E5924F26A25094E7BDA8BD26AFC4CE +B41D8964D4FC4AF1DFB0595BC5D6714C32F15DC7194E9A3A73013C45D8FA55CC0550A12D9AAE8E9F +F199FA28EFC2426D8D1DEFB93A65717AF3EA8E2D5B4AA8EF0EF38E9600F7D4E7D9F1D67A2E63ECE4 +789FA74B159BFE2F91C19B0378BA52E93DF12830D99553B6618645E26126842AB70262D96E35E5E7 +50ECA0CE3458B3E51BEE2F21191136DFDBCA39BDC07939E521E4F492F392DEBD029C1EA237BD89AF +76BC89F618D530160AB16269FA6B693CF14BDC4EC7C630025703C5337F61458FA09104EB15C7CB20 +AA4C9BDB7CEF3A09F25BC7F3149951A7CD75372993B80CD2112F7674CEFD6AFA764AA3486730D2C1 +897A264D82A91709FEC4A21E30D812F558451804EE6F3DEE2C4C437846BCBDA07C5B6CBA1D94AF02 +9163B7383CAC6E088AB1DC14ED3743EE77E26EA7AD3119A76C0B5F925C4DE305CD7BB3A09A453947 +5B9BD79BE28FC462D8718CE05F9D94CAF3387BA55E6E447BF81A9EDDD3A34E17BE66BC52B0C0BB6F +86F6F008829173816D205182ED2ECED319864A796AB65D4E3950288BADA94FA32B6F453AFDFC6C39 +A4FCFE60353A64627E2057D4B379D3240012B3BB0ED0C7876CB83C1BA5EFB6E2A03F340C2B576731 +F848F762A7E1CCAF267EE06D621BC33FC245D0E1547ADC12CC0EB58B26BABDB8EAE9CBFBAB93836F +FF22BDA1831DD01B7346AD377AA298D84628BF1C07433284B0A90FC89F5AEB2651BA2CEA405D4F52 +DDC0E74B871D43F71EB4ACE0D2B401F9348EAC3A2EF0AD295036BF6CF6F870D58E00B619D50EA7DD +77BC28DEF91D805CD527DCBCFDC16C042BF9B874E3B1567EBA4C1E70744B9E7E5BD1FDA6A5FF6E10 +1613FBE58DC46CFAC1A65ADAF65E49757E9304E2AC9A91E0588600C709A61D4231730073A36D473F +518A145E141D0A5A494441B9EA99AC23F60F54F8127B477E1CE698BB4129B4B1DFEEDF10D9E665C2 +47A62F112F5CA30B0AE5DBF3E495FF06EB28EB438CE8AAAD84D5F50FB56A3AF002C23BCF66ABC270 +7AC233FC0F2723DB99D2CFE7D3B3667732A531F5DC315CE74EDB9050BF75D29E6430F57CB6778B2A +CBD57DFCEF896E6766C8FC5C9F9FBD701CD62CACF33EE0FC95E78DADD205B5F42CC63024624BAA0A +B4DD447832B4E1DBA77BDFADD223989F8E958C8D759AAA37930664C6EFEC708116248A2A7AF3D656 +DDEAFD009B7F5333854608E67E5E588A857167ADF9225CF6C641F5E19C3E08678A281199EDDAC831 +B57223B1BEEADFDCBC8F6F25D32FCA2336C808162E8F381656E847FB6CB13969572425AA05AC830C +33DE6E030F86A3A85D2A66A77F103C7042C97205526DC882EA9A00EB8BD5519847EB424C15F808A9 +1652A6CC89B66A5731126DEBADE123C63D88A2E550FACDEB3886FF98646000C64B3A91078012CA30 +904B71737CEF6BECABD43DD702880538F5A70085E6CC6015D2163681067C3D513A8C66032C34A0FE +17A58AD4BC97CA69BF41F11D5E910FDFE9729652D3EA21F8DD8CC19160A8FC77573B1E9CEF4E790A +79D8AD6723B6804E9616466C935303E063DEE29CAA6C3BAEBF278B818C2EC2F13ED645AB452397BF +00DB8B26E115026E256746CD0C78A959364FDE6DEDDCD0F441A61A1EBA32C7BC172BB09512148D1E +BAC9E791B7D51B71CAD2DC9B83B2F99B3726607D9CBE58B499A13753CE87FCDCE21C0AD0528ED0EF +B9B2C927F57C78C626248AA2B835A0791244C5896686A66173EC9F802C4C633A42B086334D2A4878 +0E53D00809247BE64E529F96AD2F8B3922A6097D414DDE1EC76F9552F9B8D58B8E34F359AD792B2B +E50C26DB05035E7497162E7C49C38D3CD9B98D620AA67492BE5AFCA3A81A7080185C7F0B5105223F +1FA77805502A2E8C5FEEA27699858D84A95842C5F2FB68686D59FE24091FCDDE139B6463BC6C7B1E +0E90D20A83651AF00C85797BB9F53ECEC1675C7EE636D0D9E77DBD8F89670F855EE4D4800FF3F695 +0EFF09BBF8A0DAF6B8242840CFA5BA73BEB95115F4A78BCC02D85ECCE0C0F2EF6F328AD1DD6CC049 +5A3315B414A4D61DA50DA46D7ACCEFF6EE56451805D26B0359AF193531F95F6589CEAD6FA041AF15 +3067F88A0A2FECD135C56682DB2B45A71D1FA737C064EE9A4F404BB72A70B3AF0330359393247EC7 +81512482579865240A23CD8479F21C2C44A119EBC4E81B308DD8AA86E60C3DD8ADA50E0DFE8308EB +1A7F201EDE8DCFDA405AEFB47E0E6CA7DDB376DCB21D37F7ACC4D3E9F26B03A8DE0E8940CA3A9E75 +963A389DF8038D2C486072F61C0CEAF500753C7A6352B1CD0338D9212B42A4D3DA23D5BDF44C27C9 +4B88A415A3242FFE2E1B332477A21D2B9CE075EE479C6E657A4D8874A8C53964229310E01ED4F3C6 +86FEF5258EDF3B464DD6FFD7F1CAF473BBE722D60FB14AB4918E93878A8AE4773930B8CEE110F476 +7F42A52D9304C55BE12846C911A10AB9B2E036BF9DFD597F5348D42233315FA80D0F563C388BC253 +2103F05E90DBF1923F229F980A2F4585C7A373511372D07DCBACA583099EA972C03E5AA67E663882 +6DB134564DB993CEEB6E7A6659C7C5C05C310267D5F8A24EEC2D5CC3E3F3C808E6D6068D1A57646B +37FABD98ECB7BAF99E7D9AC4414A491A73CA34C52F394352F6B5A15F0FC4D88622DAC694699C2464 +84ADAC3B1D366AFEDE2A2CD2042C90516A666A19A91C80248B11224BEDDF1A320E230739E755D098 +B6A67315535F4C187CFA67ED817A035056353FC859BF286317996FFFB478A2248B908FF12ABDE705 +402224A3EE5F463DD3D243875C84E02DB968ECA1CC52C75171EA50D6A88CA91327A7AA5795019F36 +C0A19C093A1C9D3723C7568F9D41F2E4FFB712FD47F897703D7A620B586B81936C84AAED61D84332 +B3BEBC4F95B796B93EF7A1F565C494F8A65EDB21E2EE18DC025522EF8E599887CA2836069CDDD889 +88E5862977B7472584303198CCE97EF9F9E1446D1F1F5ED1CFC666A8A0C3A03E1792EFB60A9B4065 +49E0DEDF6ACCDBD98742568B4735A747D8E5DE21E630125AE0C691D054E42199C15B1F80CAFA6E7B +B2005F374A9A5F9900ABB7409CCD50C3AFCCAB1214E6A856F7C7EBA89BC3291801E1343DA9DAD2C6 +ED075C8ECA1423B43E587AEC67E6145272814B3F191B3C285639F9E2D6E148A02DC2CBC0E054D629 +5CD05DBAC1950400A9189316F0265B86A732D302C5BEE8ED233768F237C62600CBAAFF3A110D5EFB +6CC7CA3B92D965CA7C5E8D3E64ECF239FE2507FC797FDBE54C1112B28D4DA44C60AB09D994C5BA78 +D663A2591934CC052BC70CD1DCA3325C66C9CB982E2039F5DB70C848D3DCEF655B1C2CD0CEC8865F +E8E1C0A267BE4F707ECE6F5A3DFCA3CC1EDF92C760439F51AA69A4C1801E96CA4D6EA4AD980258F3 +D15C893913ABCE09101984C61B91D603053E49A97CB82FBA707DAE8AF1D579FD69C8481CB7B712CB +CDDB4D287BE995E32C02B399602A08B9DD849039B5673F1930BEC7BF366EB082D2CA5DB2385C8CC4 +5BE3FC0E31820191A814EBA7C4F23B1938E6C4D800732787CD2CB97F762DFC85D4B798809B5F2254 +D826CA42B32695428D120298B44CF38494E56240B75DF1E41E46E53C44DC505452256DFEC819408D +605FF14D6C1F3F152F2FEA96EA0AB3B472D8704E06BE9F8C3E8395CAADD06D6DA033E81ADE5DC3B8 +3DAFF743C6E9E48716003D358DF63CD7FD3E2F727D1F2D0C29962F76D5C95ED44B6F08D052025A66 +5785F264A3D5F5593677B630E628B5EA81FB37CFFD7A30B7FAD226B6FDC82B0878AF4C0EC4F4243A +807B9839EA62BCBDF7C2E9B30A623876E632E084EBF4A21EDA04FC88A1C07021D0C72EC3E969D449 +FEB08E5826EC20E55B21EA71EA59F6E3B0710B0DDAB3261B4A2029ECAB68C19ADD5174E55D5E984A +4E5F38F592A302FEE6ECE732DDE841A28672C620CC5D687455A5C06FA9FE688394A04F96312ED025 +B7AA6FBCE2925F3AE559CC1886BEECDB70822E2E5CA3F732A87404B1536AAC469989E9610CFA440A +CE43875A70CA51F36CB6F629D9424C1E35A88F92D5DA3CD8CBAE6E8425A36968E21F4F30349749E0 +205BFF8D552837D6FC39532525370BBAC833F75F1854C93FC533A4AA53ADF7008173A70D94A4EBF5 +38EA9E62BCDA7C20E0A073BEE2EFAC34D2EF1D03BABD5147659E50B557045B2EB89DB303749B04D3 +F54B43FED612FCC68206E001A7AFE90230D9C12F74A32C7EDB5D0241DC3A5D51481FD7C8FAE08FEE +263FBCED7C7D911B3A303C835AF5FADFD218F61A9D6DE80485ABCA88200047B094441F7767B97A24 +E8C612590FA2407BAB1E8B56C71914EEF2355DD97CFAFCC192BC06FCE063D3D9D1A629AADC75E3BF +207234C208E7E30663EDD691043065C9CBC473D97C6D4DD3DFF59D6A9ABCDD4412C3128F603160AA +D8F81C6E7A4DCAF35F3A99B4EA10A34375B477C2BF846521A7EABD4D28078E9340452A198F3F5ACC +3DB7E3908939FF6E3709C6A3FD9889439A4AE3E10B618CC92E14B68429A3AD2C80940A1079452EC2 +66F254657BE7D79A2A24084AF73F6DF71FBCD32BF6913A3FAB25F977787F7BB0C3A3E8BAB38D7A2D +B0B4826950643DD1E03BD7DD1FB149A33862A89226B7CB454DAF613128C2075470E42E70A9444A8E +6ECA526345AB48E6F5160BA23B5BDDFDA6049EC44ED1461C7E0DD514B16E2FB285F72039DE3C7982 +EFD40D7F6C8E8F4CF35AC71B467BFC578002E8D2239A2FD2C4BCCDD8AF3D7DB1F4AE7F2D2E0811DF +9D0155BA6EDE50B5F052F14F6AB884FFF244D8806C07EBCB49ED22D85DF696995991A954AA97A1EC +D86ACD76E061B7541E87997FEF0657A826BD88EF3A4A5920462C6595E7A156F453291CA044CED810 +860C3B0149BCE73BECA713040664AD0591304106129600AF71317B0D2907839CEAC99515D357E980 +B1937B6E1200AACADA205421001F1B2F91753E80D2263C56AA164A74701A8D5FD28E46480B0DD963 +A683A1F355D7FB4463C7347C94EA5E2CA40B60B56297CB22D972C5BB10E56715A955605256C1541D +9F3BC5768A6F355CD3B863F0FA1A781EDB49368F51B29481CBB41D4AEB07AF9DBE8F52C5D0FF75F7 +FB6431D37D6AED84D78C778871CB0F715B4F07580F23B586C969C81B471FF6A6C7276F7E141E02A8 +584D4B9AB00E7BD643D2C3FAAA299B1F1E25048461952EA42D4882768A70DE46B213A287F8D31AC4 +6D5436F22A796C05D1FE50A9BC2A928066627A0D87DD57A3AD91DB446404B41557D1457873482005 +EA20916BBE46C613F456C849D46BA79D20627B446B2F49E3FA309AE14F8C420CFD94922CBC0FB9D3 +5A0F7DBEF577F1849A1A80E0011DA8AC082A8C6F61658E65AD177ABDF23EE17C8CF0D26B9FA3A6E9 +4837EB9E930336889767A8D7EA3CE980A8EA95528B004957BE6067CD9BD8E02A0F23CC1762CCA656 +D33412FF45E917FD4A03EB6E8C1F43FDB0A8965A33B4FD26BC24A20B304CA817E88495BA9B361A3E +933717FFB0271F7F70C5D3CBA1E86D0F51BF3ABA194DAF32C35C796627D00C7B2271ACE2463E37E9 +7B3C826CF3DB60028F240F9452CBE08F7EBCC5FDB1BCBB3C327A9F450B9E5671916101D6E3E5E458 +CA31F04D12F592F83BADA2C3683D3886AA3B403963AB5DBE220FEC00037A745839F67A3635DFD3BF +F08F367482962DED88ECF6322852D643A54D5D303EB04BFDDEE9BBA1EBCCBA7C653B3A613A8E719A +DEBE3CE1BD7E754E5F4977E863E3C2D388A65227B451D4F3A4F94E06513CBA4AC1F2F511613FF035 +611684CCC461599000E546E4D972CA6960E095A526E4735A23421A4C9B597ECE08AFA2753592BD16 +DED93255A1E33DEECE3C5EB77B94670E8137F2A4A4B98AC193258E7DEA5DB8408A806188F2D1DDC4 +40CCF0E9A6E2F0C78FDBD7B68DD4939D2458C1965BF8BED4564B32462FFF3EC892C03B11D3EA813F +AB4CFBE8D3016329C5B7E3DFED0F08284D44AA0B7A2F6BC96EA4503E8EF52A64C22BED6B452581AE +8FF8917D53976471941A9116A2D878FB2541B561767ABD4E31CCD8A590CA03494C62AFFD64EA0A1B +C779173DAD84999C7A8D844EB1259DE7BB5B25CD023537A474A524EBE4660B22568949E624D8FEA0 +AD37F4CE1EC75955EEFA49C6BF1803BE87E9C9865FF3F6B8525B8C15FE8835CA153D27E6C0FF0CA5 +1029A7A9185D25F0F14D86FC797DCC1F99EE97E2054B9C2A2E06FDBEB8DEF6CDD368BF23A858D9F8 +C1DEFDCEAF1B4A8DE5EAFC604CECCF0D285BE00AA912EAB66EFF4D37AD2EFE34853BBFD87CE09B18 +749B489943EECAE7887B006FB827D10191DAD18466CD1F86505879310A8B171F902EA0C26A388E13 +B53C700272CEE2BFB47ACB58247C13449C6BB9D01232C32517358F1A3DE064D43C18F8827D53789C +CF3CE2EBE78949A6ABFA1A6B8414CE360A5E22AFB7D1DCE6F5A06182C3B984B4F9BB1A905A9D5A14 +83750A1DE0A857CD5C06945EB7D4A2A6BF1237F32A154FDC06D51A703D44FE052FD3C53E9E8F417B +35D1C851F9203A8997521529F21AD8498F96930AA77EBAF82EE02A57BC77C792D9F220294B45F48E +A8FD94E01CD25645D36D168923562F3FDC93CB79DD4760DA0C103C2675722D7A1B79FCB4245ED12F +A0DB52492C9CCE58B333CFEE822812F7DCA68E802C451B5CFAEBAC608B950386B6C58239D1C62D62 +4DD5D15782FC552222CCA06DDF387B373E32C3C2864C63C768350C37283760F3515A5B0AFD66C48A +B522EB3E808C061F5CD6BD96CD18C9839D30508E7D4EDB88E8F11E31E10919B16B7971F06D7877A0 +58D8A4944C84FC6CAEDF3341B48B6E0D3C7B85D710E0C35F5B5053CF4B4798B3778CC28B2DC7AE0D +F3A49F9F3BCD8E95D746C35C3F47D68B8AA35D97AA08E711B5FBE70D1A623C82541EBDC51A827D0A +69E6C049087AD26F256EB7577F58CCFFBCCBA5A95D093DC29464C9A38DE95BC6B1853963B2DEB0B5 +7AD1248D6F1625E115EEB9510B5772AAE4E3C866657DB0B3BF0E0AC345E116F8D4976B770876FFE3 +748C36165522991F46A36F193DD1A1C94713673C7E4C81582391B636C72DE94CE6254374F99B623E +5686C13D8A8322E83E11BB0B0A896C6A8C2C4F756C5385CD7017F26D23F7C3EE97372C868C8C9155 +81723BB6B76B4C3CE8998E4FA6CA40B633DFDAA59BA902A4952DA90EC4FC3CF0F2676ACFA7F76F78 +236FA2DE10FD3545357215246BB7E527F277C28B353CC6D79DCEF21BCC8F77603CDD58A2CCDDBE3A +9802F941CED8E035313875319548C41992A2BE939A17CC109426E33825AE59BCD17CB19F50D972FF +CBE7D9B4B0BB095303D9DC9D406696C2508D6CE99E11CF00F6461147E97449ED5F486D480A86D3A7 +ACECB7E9A945984724EFC21C5079B1FD03ED803C2DEAFCE3327D2D7827715FD65D9506216C88B0FA +26935E95C64114A51919D419038B1A7E9C1E829FBFB53275093752DF19891A97F3CBF7719C1FD6CB +17019A6D2D25360ECA804C4B35172662CC4769D2B785C6C87E5A4ECCE31704E59F71263B7C3CAEC8 +ACB4C7426EC25F11A0042323EE6C3EEB04284DBAE2C770BC419DCE79BD4560AEA41571C3B595F525 +60191DC7A8FBF63D413A77A0905E517441B16C2B501EA2F9E99CC38D052679F288FDF1894542E3A6 +6989A0090185EB2E75134BFA3D9147C3DB8A621D9D35E37786853779E157B47F71626D6B3E633005 +9159C17596C1B87FE2B4FF47ED9D78FA4C2160077276C8B58CEF5DC030B4A5D83CF257096C047FE6 +4DE307C598B815058E72D5F57DF5C369E664E137DE29349E2F9DCD8C9F4EBA6E765B6327D7A20DFC +B20711273FD8091CBA605C4C494248076F7E03DF65A6A50164980BBBB708741E5BF6056E6F996DC0 +7FFF408C5B8EAB8DCEC315E92873228C805D4440A6470E3EE3983758DD211C9CECDBFAA4C9300CBA +00608A4B2404A3C7AF017A3B7E67F39F0B51ACF950D3E75CC7BC2B8D3480202FA958E8EE0B240501 +5232EE0D264C7CA02C18CA45CB3C2DE322D3EB7F00F9455DB6C5B1F4E59C3E95520EC36D7D903CBB +625D70B54BF6F8255E412604BBB29FEE026CC660577F91DB1DB4A613EEEFB20CF7AE3CD89D565AC8 +38416B01B5DE4FFA5550D17FB51FBBEBE21CF1D56038863EE931B90DEC2E211ED42BA92EC244D4CE +2C4EC5CA87A026992772DC2AF754FC982B94F36EA7B7BF75E0ECE90CBB2A6AA1A012E8898BD679C2 +3CB3827C35D5D02F0569C7AA82615D4AA67518ECF668D3B57D6EF1A8013424AC2268BA0D9A74D588 +79EDCF6382A89D397864940303EAEC45A38304BA8B1CB198967AE23EB81054BE74B16909A405E8A7 +799CEE3C270FE2A6DC50BD7370B6B2C8FDB9A87D88D5D40348D3984E39C693B6F4486D994778607A +80A3122872DD65E40492107C71C3CF708A9717E9EEFAFBDDC239C53AA9645B711038E59C8B861B37 +411AB2039BEDF9CFD00F08D9C5D76154427FF5DD39878CECC5D7BFB3F1F035087185C0981F3C2139 +BE84872FFAD3408531C4EA9387B89F5E3EC779E8850D50992DFDCF9132BC551E985943B07618AC10 +D1150451F0844C0DC41D6E17EB508DC8689EC726400D5A7F6FEB3CC7BCE05F09228B7CB2C5393664 +D8DD9A4B96B1020EF25D70AA2D91CAE93AFB5F2BF0AA18CA5C599FA1A708EF35BF8F7FFEC9AFC1F2 +42870D028B2B1459063B493943EF1283829783E1010242E5CF4DA39D93D506F3892936E7D6CF1124 +70A521D397438733D053944CFF12D6FFAE8246F20618684F263715AA98E15D72A526383E05C23214 +B78338E5B476F0981D90056E6E5D0DB66B1DF2298E597B2ABE1D817E18BEB056E65EDB4234342D96 +00470B1420C9210419D834E431B82F58608C87AC361A02D0F1FE4B470A3D71E0D21BB87E1023D428 +E23D596CB9E1A2184403A16E36E644BCCF9BBDE27290485057E62827283E7380AF786BF395B3961B +A5EA469C315763FA59E0F176EF81985F38B882DE56A74D128E256D1B89939728E55A92ABA21A6B78 +44FAC1BA7BBDD8B34A18194A2984B000380FE9F672E83EFDBF276FE797A325815B0F25CC95C97A9D +ACF56D583486305D7C9E51A7E337D14E3B900333EB38FD93A99587DA2341B10C059C71CE080FE753 +3C0F059FA40E560AF9C4A41A4BE6FB45846FF8F78165E10B4AD40F264BCF5596A1E8EF8CB6EA4B1A +3A5C69059AB1563843679ECB2511A90E8898F54295649CB73D277760D8D04ABACC7BCC6E777A0530 +E2067CCBC08673F9C8C178F9D672AC8A15E5367F0C5651B53E75E0CFA57C931746AE1A679C246D7C +9417F1CD89DDDBD1173C2F880B7B3847CBCCEBF99F7122E832D7C9BAFE2B54CBAA1ED48158DE3F36 +238B76B0E67644A28AEA996DDC006F6AC0242E4B667639E7523CBC90A0561193C1AF34481C2EF402 +EE43A82E1EBF4E3D601BB36B2D95CD93550D61CEE7A94E72F6D30C32C8F91A61E964B1F66ACFC398 +7F95D4028F116E9A9A8474AA29C1C1A984BE0E393BDC41DCEF6A6F1018DB60D52024899D8EB5D55D +324D73F39BFA47377B9E15B3B06A7585589FCF52A54684173E5183367E7B0952DC4BC2767C4C6247 +B1D6103E52BC7B7EA6298F454C5D97AC575F19C10ACDFF4E10C7D3755CFAB4200CAC545269FF1D8D +B0D607C7AD47F40DDF257AB4E7D0750577003C13E4941960C3DD7B0774DDAC18E8ABAF8F53E03CBE +F6D57B44F24CF821014C064278FD51B3427593D17694B4ABCE81F49CBB984C5878CDF0C38D1ED7FD +99B0B9A3BD8D8FF6219588B3B8FA59D0CDD1D9B2F65122AB45E48F1757467B9204926140E3C350C5 +A927A2E700173053EC35D3F1DA2D7258714C97FAA857F0898917BD94625C6D1E2D77138EFCAAAF51 +7B17FE187A2212C24A881A2C6A647DEF6376ED80AE4175C5EE80921F001995B44E49F0D33DD9075A +CF33BB03671C0BCC34AD5784AD1CDFED3A6D9BA103B3DDC1CC2DE74DBB576A0277715275218CD19C +A8899209125266D8BF1286F881DCC2C383749D1E768D670F4099F7DE959EDFE852583183C9111601 +2881A56A24AAF020EA45CD5F39660DEBCE30AC1C7B8CFC60387B1B0C3E361BE612FDFA9F01B7E4B4 +A18839A2C7E0E393EBC5AD9A8A4EBC316A740C1C295D9EF5F4DFFA0667F9582C0BB837B142C4CFC6 +B1798E9476D0631111033B8BA75A10FDC800E2AB1E0E829632F869CFE4737BE9E2800759EE0831DC +7D1195EAF80555771981DD6DC6606812D92CB8EF86447F5F6C6F626D0E265C67E52A6319189EE349 +D48E49DFE6A9E98F76C414A1E3217AE0A215A17E54AA498F4ECDC50242ACC7E2322F63BB2FF2189D +057E7354E32A3ED1803116176B9B9D0129930F919E2FEC280B2C8924E49E7BB75768A2EE1DA8ADBE +D4E3589906DF1B923AEF84C1BD327438B731012E69BB0D43A1842CB88BB54EA4516477F704CFEB28 +6E3EA483445AD4D74586FCF32E96D366901084365F693A53C5FB532FBFE7BC0CADC404C4985042D6 +8DBB90A6DCDA3531EE324D558A214F935CD9FCC9A0CEBE9B5FB0323F4B3820529599EF48EE068B5A +CE85004FEA2984F0A86F5AC9D56163BBFE1142B774148F1EB0A4DC89C3349052533A7DE66729DB24 +41B82F8F7360111DACF69293C9B281A0534F3E9E9224A75C49A832F28B2E497262475507B6DDFA9F +01CA0A6696E3F5AC7EA68595EBA0C2EB8A47813FF936D84AC1B23ECA7AA2862B793CCBB0DF9FDD49 +31BEF354CEC12FBF478559FEC29F81ADF4452E83963E56541D31F3691C93A50F0BBA5E9552C4F2A2 +3A6E53060729854A3DD71CC4308B91957DB19E66AAA18FA67055A950F1C2CFF78A03BC1A588CF624 +696068068719AFB1001C4581EE072113882D9052B21E355D401ED8CD24D067B99E616BDA5A0A5A93 +36FC499632B79FF2FD0DEFB096EF46B75E2D4E0F48DAEA239719FEC4D9A29818F5875FC5041A9EDB +D26CAF0ACE14CC80BA49BBA59E918EB3D8F1E541AA16026585A2F72DF7D83541816DE46981FB3EFD +0C30E458CFAD04C79421AB7C4925E23AEA07F9F018431C790002596D26BD9663B51B699DF53E4882 +CBC34EDE88EB55045B889B6062E35FD1E018BCE785157B85EC3B9CA6C85D4B16238275385B8285DB +012D8FB7C9F5B946A41D7A0FB878FF72C39683144D8A007CFF631B43748F2D5FC690300F9BC0C837 +006B92ECEBE0605E8C3A4A400E18AE8997D1B45FEE10068E247C647CF82C6DFBE5E881D511FFA687 +B7AEB78546BFD07D5F7EC242DCEF4930D8AAAD8C6152B6642AAC325963FD147F236BB850A9966573 +9D06CDBD7CA79A527DCF461E33F22BC9C5DB00DA2BD3DDDD8C99D99793BC98282AA8872FF96C3942 +85D82D9419EB78B6AE37A5F519397700F75D624A09BD255B576E955A323E784E8FC31131F003B0E3 +024A4F58FEF2A6C043796201FC425482E1155E229D1B2D43EF7B0D22322B22EF5C9A1BE026A1C3D3 +75EDAFF99597E1E5477952A4E8D2ACF5D014BC00DC2A272FA62B6983E27D228881E2EF2B8B95A681 +CBE90C5FDE16331C85222FE2A16F0A3C3000A63E2E21666C0C119F8AF89A543D37977069A5ACF155 +6324F05204CE8CAD50FF4FB630D9CBBFC324DEDA584AA56A99D3A76FF55BDC2C2EA3A021361CCD4A +83C7A5E2768D210FA6DE889FD48A39D679C94EC3C99A8D33FF11377DA7F6F1B71A2A05B302ECDE95 +4F26773F39AC881542F0D0969C3995C3519A8EF70B4220D86BF01BEECC6462855E7B686E1AFF1CA9 +1FB8FD8B4A69E10EE0C2AD94ADD44449506F9B6EF43641F2026EFF6E605C670560C2B74706FB949A +A7E8CC6A2D0D6207E457E7FD87EC1B9092DC68B9143947CC8ED14AFDDCBF8FDDA228A76847F96802 +E561F67CEEFDE45AE587673983FC04C96744DBAA83F2DC838D633943C75DCB9E6410474EB27B348F +26E505F0AB90878940E846C5E9F3C5FE8C3558C3236B1B88C405716949B8506841CABE1717474BB7 +C30DB91CDEE33B0F844811762FAEC535BDCF84C1C747CEF9B1FA61D2AFB5A81335BC42C06A94D7D5 +9B7EDE55BCF6F9867AEE107555CDD084B7684C2C87087475A39A9DA6347BE281CE5635A4D07865BA +98CE26C1465B1AB0343F49FF37B4D0CA9F3BB693D78DC3B21925CB996A038DCC172527FE57C07460 +EF39C07D4396E7FA970D9F22ABD21A9C794B64AD96762C7428F59A8757C36D6C4FFB23216195A04C +2A2C2E7B10EF7193931544D782FEE4B91E01119C5553BBC6252270A8D8C56DD62D448F5AD8DC69CC +B45E1F17F0AA1E445129DD00F000005B23D38DE93A3BE55A4C041947F36B4E4536E307D0180553F9 +2E46B743881CB5D5386C48C7D5F84C2BCD06B9C501F78C7EE61FA23516791FCF4DB278AF688A2E60 +10A56692AD92008497487EDFE4BD5FA083FA544138B20D6940020887E35D46E093B71F7A04A67460 +DC8116B4D4839625D7CA6959D6831CD93F81AC4EA2709036DD738364FDE71113BF22EBF13DFE1642 +E564701E6F0FFE7511EDF03FE448C2B28C64FB7D54B94CA576E481FA56B2B18AF10C71F699B6BFD4 +7459CDE1869D0FD306BF489A6F42E5B2F05CCF55BB6B9526973D19CB134CA7F13F1DB3716F8CC217 +73A832568C16250B5CDB16DF24BF81D49F5B37018BD310262EA7078107868AB0216CEC83CEFCAB1E +9F2C665A31585CA04DC01879CAA79AAA5AB201B516F7052B01B16BEE5606098393B0E5D9F9E5E3F4 +EB20F63C958E796DF41CF28839F5C62A0431648745D7837B519F3AA36BC6C08EF040CCF53D9B6D8C +0C7D1A84D707EC57A3C6AC9A62AB37251A01A5ED40FDEC6F5BE6E34C6A91D058319439778A2EE5D0 +363E2E1F33463C33327D05FFC0CBF08D5BC457C7230448972FB9B4D0D782BA7DBF10D3FFEF8BF523 +6EC16D4DD6D0D870D9D5EB5C64C9A46A4F583D4F831FEE74B0E5B33A09ABFD4444929BD8F638CD72 +EAB99CF2E9551DF427683964A592E49D186F285258C5D5F62196A98532421D73E3495F82695FEEC6 +E1952C562D546B28618FFAEEBEFF03A57F4D855021F85B0C7BC37FCC6DA9AECA099B646B99D41896 +09D3FF2D56422F8C37E97640293EC7C90E3380887836F4938FBF495CAC14FBA5648D89282D8D49D9 +1AF73ED36581139D8BD42551E263E830EA3C6EB381D85C42D74C50DB0CCAEC03F535ADE92128A016 +0E811C34748309AF7604919B66CD43EB5CA975302DCB6076FEB6BDD6FF55976FE990FB0CE9ABB11B +195403FB26E3D6C6A0DE1C5BE79E171A61E21F79EE8DBE7A832519813EF6B33EA098C2C32ADEA219 +AB2AAC8B093F40000995539D1276D5F2EF84CCD099B71FE4269BDBDB6A8D59C86F7D2E3FBCCF8773 +D0FAE97640BC1AD43CB4B992BFADFB09DBD0CAAEB8CD9DA264187C4F97300E9A6C9DEED5525479E6 +05C65AE336CBBDF4E5D7F79AD098F977285E065579B748FEAA97F2A753E1F962FCAB68D72BAA8EE4 +FF6691C23E31BC0F3E981A96FB440404856AE1AB32A7205B17D411D8F21C8C93B704D07EC594422A +BC368CDA2B1610CE6A973F4474E12B78B532666797F5755D269772C9F5400B3BFC6C58395D38527E +2CCCF29B56123F7DCEF3BDE5DC1DFC5B0293BB125085B1D2D929BC3EE84F4FAD571A4991C3DEE03F +2DB3A3097E52B1A7D5C73CCB6148EAC62E8E36DE9A71C57638C6E4D5D9DED18174E8C390E50B4A5B +913C074EEAEBE390B214B3A68F02862B9A296DB4B409769649E51D738CBBDFB7702E15C73C2AFC6B +C37CE15171F4E822CF20EFE55D9F061AA43E648989628FF79E65932390CBB15D8E621333B18B11C3 +BDF96F841D7434E01AD501FEA964A75B248A35CD9DF9A37E48A1E5A09C624B93CE44F0042FA00D7F +9EE89B9F7AB785E9C718CF6E7228F743271C2C9BBA17E5208B920E44E765D99D86650EB454B0FAAA +112753AA1BD3A24239E9C5FC47EEB1547AC9D23731B8DC48B9707830DAEC60C8D3790BBA1120F776 +4EFAC542CFFBCD5C05F9510B27B2534B704ECD36C8B041FD49A96881302FFF5B0163A2DD09C751D6 +D6AFEA9170A4F4C4AB8D46E62F763FE1BDA51DD1CE4A27E772F3A2869155F762FF26B7AA6FCFA4F1 +292E56F03AAB6322BF867E7710C34D43B5D85B45AA68014AD7879EED051B1933E491496E3E26D9AA +8B80A07BF2B94F1077E84A9726F08199887D66DE7A307BF33C30DD9CF3DA188088C03B2BAD09A217 +6B110DB2C868B53DA9A66C85737BA66C93C58A259860E294AD0191E3A72C73F40B0BD98699AA08DA +F03587B78F391F3A4313C58D9F29B53C70785637BD0C58310109C54091AB0A34CBB0C478613A7AC0 +FB8F0A8B4645AC966395D8BA775262CD291136AFFDDF01C1D83DD4EB3B59CCAD18057FE7D92A8CD4 +A58F22508D9FD7CF356571F701BBB23E749BDDCBF8A317FDA0AEFD952BB18545610FFAD3AC143D35 +1B8DB3F66293375E0E50235F0D0466932181D377EDD32A5F0FFA4E22B5A0CB4F343D9A7E4A342E9D +09DFF6C697630CD3971802C277A5590B8CA94BDE6B38446C794D072BBCCB724D5BC208EEF1B018D7 +39373BB910D668882CAA779C2D686081DE6A2606417B54D7C20E0E7F722648D893E4EDBAE8F00D6A +6DA3712F91AE860C756D1127D133AB828E9D80023B50B162C5A1C5CDF70CCB3FDD7EA060ED20838B +E1E50C4094C9E79E1A0187CDF780CAF45A725964F004253E034C5BE46BBF89D94631F1A33BAA35B8 +4FA2A9D08481C6674126CD96ED05DCE48BDA069D902D6836D5DFBA701DC0F98A863E64F0E312145D +8DC0B77F25B43AEC729A1243B45B08CA228DD6101CAA2AC5ADCC8EFF84A4CA3F254176C2CC711EE6 +C273835D0FD3528ECA2A976B88E51FE347FDB60F32370B66D338931D6581630ED586F349C638960C +31AE4204E89521A96E1219E696B913DEB2AAB7A3B022D06F34FDFCB810A04E60A4FEBE284C2F063E +0AE9EDF87704921CCFA193BDC912B747E13570066223A49F1F6E2AF0D4D65DA04CA876FF7A462FFC +9C0BA2CC545C3BD36DBE762F32B2D6BE5867C59F479195C92440DC165098B74EA5C3AD93CDF2D410 +B04C16BC7801E7956F4E5107450787AA592493171C3628E6B8F49D4F8429EB98DC52EF025F001387 +BC1A7093F7A99F10B5D2D7DD8BBB393BF6E56F08F4F7FA1A343F220D5A1EAE7168C74D41BE1DC1A8 +3BD65B72B982F4F7B34F24F97F9EC9A91011064031FACFF2A14921A32024385F4E061CD07D152E74 +1BF97156D951A342488FA7F5EF934CCAD13E2753A0AB7A1F565C2F7F6B349DF03BBC25BBD972A9AD +F809BB5C5048A8CCEF9297B2ED3324D18867F293CC66E88B3A39D107B610DFE79A3B4E83A96D3D52 +A17FE8A62C9FDD271130148366942C9CE57558D023DA5F7501319EBFA33DE9E6D1E76D7C20DB8A09 +B657839DA99F3D8143F1EE6253A3295C9651FA4366547893C2DC7ABCBF4BB7609DE5D001E0A36D9F +FBE01F7D0903B3208AE8547E2E5F14EC1AF4C2535CA8F4EA37E3F3CE172C7A1E8308995B1CC23E6E +81190246BCAB6E755BF868D449BB02A2AA87C44C9CC0F571ADC72547CEECBE104BB274B8AC16DCB7 +5D5F458D356466B921ACDEEAE384E2EB1DF6EF393B41B9747F0A4FAEB4AF1928D9AD6FB7E06FDC62 +1E4C6FC98CFB43F88584BD55D9B97CC9549093EDE586912161931162B1B1D52D0443260DABA02AF2 +B4432100D5506546013DA703573FA8013685CC798CE501960093DED713FFCCF89CA2B9106390198C +29A00864108CDCC1984A8BAB53919028C01B26ECC7925E38CBE6CCA8978EE21C2B06E7B3E48FBA97 +8E2A7D186E563C088F84AA23178B60E4729EE87D67B1091F3B6973676C1CBFE6530EB773C62E2C24 +97014AB0E8B71A1F4E86A378AA26591511BEE3CF3D64C94848582E1354E1605B6457823F2C5E640A +D3802946BB2E7E8E594E8C04B430C2385DD40746CE8534F50842E74D7115F3DB0C72D1C9C607C657 +3B094AEB73B7A79876CFFC3E2F8C9FEAAA07D3BFCE05B61F7749A8793BE90CCCECA2D7077F25E899 +D3331FE161A7E86C842495D584C6E4A0880B2951D8A13B88C4672080A0B1BE36BF47C3ACE7288CFE +41A8C1BAA6F0814A947FBD6B3AA72B6C73A8C578CA51CCC96F2352316C467BB960E981F2B6485BFB +44B577E71EFDA16E7405954BC7C9F0759F5A9F1EBCD2FA9CC9648D5831A68887F41B15081A204C24 +B4B992A231DEF9E698D4C3A25B6F5474F5BE6A601F2D337A58A0D21FF37FD91EB86D1D738893A03A +69F0CD743F611CDFFE69DB2C6ED0E4611D56F803BB0DC06E7FE85A303839612707647B1BE9FAF8D6 +84122CA9E5CB8BDE2936D3F4FF254D31529D7538BBD4D35539489F9E7316F24214B996BCDCF1818E +749A71CF0E8845AA1E2A58AA62A48E02BA4564625D20AA220EE719608521D7D7A7FCA0BD8904A401 +9819D371F3F59D46C1354E5FC1A6E5F79B20CF4ACA2BF0F2DE73DA193A6F9ACBFE0B4731C4BCEBE6 +D96FE822965DE965232282A3A130361F188B3AABDA95A8A2790D9240BE008B6A6DE4BBFCADA05B67 +86B9BB8E0DFA0C30043A3B07ED46277E07B9808422C8ED16758B9C396F4EA929D769785B2C9568E5 +70A83B989B25CE200F1727D41E2B702E7F88F1784F4C83FA60A74EB26B2DA95126E508ED519A61CC +151DB6804F61826C5F86D8FA89D06E526FED97A0DB88EDB432FF32C1ACC9B622EEDF601081AF7B96 +3C9CFC1D13E4A9C74FEA0A1C8E3D8653CD92A944D4CA6B0D306619AFD503506D77732D6514F604BE +4610C2560931BDE0B40939BC1D126B0E97F72AE1B4A9252123B54F7A27E0CFA4425B4546526FD741 +CA77952B10D13E0AC2E32006A903808FF0CD013F936238C74CC75FD915244C56A8412F37F0134840 +347699508D6F3D7F3203A25B7C70100719582CD588590EE34B3AB13E255B613A6D00386A0104CC5E +D2C646F09A88888D3751651D5646C5227A3C80E8DA1B0A331121DD2429F1F4775D30564DFF47D01B +BE2C6C72CE4D1FD9A2077C04D2B0274B8916F6A9D1A4A6964A534F47CF241D5A8E34B23F85BE9ACF +FC2FEA961F277539F215F8728D6788F67BEAF45502839BCF23D8763C3949352F00C579A9A4FC408E +C625E310DAE61512DFE6844E82D36A2F81709E1F05B38AE9C222ED62C961EE63593CED7AAF73CE2E +D3667740C77B309B93EEFE1B4BA65D48575A66BE86743DC9E5D3C2FF418D11F7F211B86E827EE1DF +C3613E7498030F07050524536D1F8A94DDB6698BE7B963C55CB3F74B676CD815A7B3DF4B1A0EA2BE +1B0B9A11FFBFD5B1FA49668AEE14629316AF436A0821C20BEEF7B3480847934A99F6D85B68F4DDF8 +859A754E009428AF89A90D1852C220A607FF0806E8080726EDC94D691D214B4521C147C4273AEBDD +BB4A697EF16448CD9B2FC95293305858DECFD406B89B9F3FDAE2AC579E80CF321EBAE5701FB2F7CA +D8ED04B4A63115886D45D6120F69AEF1A21D80AD3C2D35D2899F1902242B96CD349E0AAADA40F7A1 +1282B6B52BDD97708E58DC5E2D22D1153E5FA3F3B300BCDFAF98DEC2F4E3C82A1C85F985735F3987 +4F557579F422664E07CBE19DA680EFB0FC82C323EC5C4644C51709AC8D674608A8043C91E6C7988D +430F10BA6CE1FC7FC0604FCD8F723895250AEC36CC35B3FA14FE2A0D24095DCC30B2093F2298F5F0 +A97676A0BE66C3DC9ADACFE2FC0F721A20E945AFC1096A619075D5E9A264C796EC6C90EF1AEEA8DC +089B44FFC13D27CB2370070A52D4416C53F364393E46EDD7EDE00799960CE6E0D57E4909E88ADD64 +BDD2B0EBE2D73FA6ACF8B40280DAA0637E705C65AABD523B8815F22F23E9FF81E7829C7E4BC980C9 +143AEBE1A04DC0D253396BBB7268BD5AEEA356B610D5DCEE03135E00AE34388251F31714A1C40E18 +2652C48CDA2211A22CB6F02490E69A44CECB169754C53B16028D352E0119F5D5FAE0BD7EA1CDA647 +12A6147374B64244E21E9EC9F0D1381AD22D5B6212B26C3F9AA5F6045F25DD9F5EB4489EA39B1945 +331AC70510C5752557DE21D0A6CFC1EB10A98FA867B76DA6E4249469F591FD154D39E89364A43DB0 +07AA0D7A911CFAE6CE2B557997FBC44F55A27F622BD7B8B10EC9F5D10F2649A646FD964AE1B111B3 +5B46A252C4DEE44E7426EB5739F24E8A390694597DB3A1FE7800C97E59558322F0E49A0CCE2AD94B +1E2D1026AFA771723E3F523916F55ED866C9FB4A2F759651C613A2CFF362028CDF9D38F05D4C7C60 +24C533E930B64B099FB1AF04B01F5FB9CA6867E6EFF55A772C5391831059987E10CBF987E3F378E0 +1329F73D54DC0484177D3C3C06F67397955FF1CA4EF8AD1606B70455255D631A7D6EB92BFDBA14A0 +FF28B2ACE7E81AD666EA9B3A0F5A6BA3B5DFE35044FA4B3D8ED956009C60E98CC132F2E84967F4A9 +8A67B336D5EE7CAF7DD1F74D1FA08619941361FA7312CF225D89CEF97E864C8369EAFAB94D97F056 +5505D825972B754F6729596EEA91210B75DD8F645382ACE36DE60819A02B3B48DD00F5485F9264F9 +FA926D732E2C267B0BE8CA98526F124F97EFDB86132C5EF16B103908172FC51F286FFE45FF253512 +E0033F037FF182BA536A9EB2DF2D1DB257D9C86C46E1B002FB32AC70CA9462E6EB48994752CEBCE3 +9F08ABD4F4B0889283E55500702185A841E328 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndResource +%%BeginResource: font NimbusMonL-ReguObli +%!PS-AdobeFont-1.0: NimbusMonL-ReguObli 1.05 +%%CreationDate: Wed Dec 22 1999 +% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development +% (URW)++,Copyright 1999 by (URW)++ Design & Development +% See the file PUBLIC (Aladdin Free Public License) for license conditions. +% As a special exception, permission is granted to include this font +% program in a Postscript or PDF file that consists of a document that +% contains text to be displayed or printed using this font, regardless +% of the conditions or license applying to the document itself. +12 dict begin +/FontInfo 10 dict dup begin +/version (1.05) readonly def +/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def +/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def +/FullName (Nimbus Mono L Regular Oblique) readonly def +/FamilyName (Nimbus Mono L) readonly def +/Weight (Regular) readonly def +/ItalicAngle -12.0 def +/isFixedPitch false def +/UnderlinePosition -100 def +/UnderlineThickness 50 def +end readonly def +/FontName /NimbusMonL-ReguObli def +/PaintType 0 def +/WMode 0 def +/FontBBox {-61 -237 774 811} readonly def +/FontType 1 def +/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def +/Encoding StandardEncoding def +/UniqueID 5020947 def +currentdict end +currentfile eexec +E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89 +699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641 +2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2 +5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF +9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A208511C6D0C255B9A5BB2FDEDB4D399C6CF1 +94FFAC236883767C0F68F4EF84EE696B677DE704EC3B097384F2E673A1F51692B7B260693738C211 +9F7D90FFDB21EB715FD5B8134FC87DBA320EE54C2CEC6A4D6BB350555EAFF2EC4F84365CCC0802DB +B3BD0E3F0D9F858647DD637725C2CAF9557FDF842A0DA6A0CA0F1B442EF8EE6CBF2B03858468A466 +AC5883CBBD3815B283343B39205803C02C917D06825C09E2BB14609FA32C28D720C0E14A4B12D4F1 +25FF6281FF324DA33A56FC49987AC7D3AA206540F8127273FFE9A3DACFFE2B1C269D3DB9A811578A +C7D532C2EFC18376F473FBB2B32EF642B19CDEC1D6DE83643723E3C6DFC87F97A7007B6081894BBC +45C955B7001EB36211B26AD7A3D07459CFB33F9C54A40A360CB802FD202C8E93D4DB888B325CE246 +D02D1220ABF55CE646DFB45F07CB848406E470362F80CE4C02D98DD845189877732744CC16C7F566 +9F77EF096EA55AFF98AA103EEAEFB971731EBF3782E6AB725D4E9E35B2968689E8007C038CF25B6A +E69451A4731E79AC22BD268F56942A233E52D71873E83E00A1874E04D3B22E72FB2D0671AF81C698 +53C389B51F4A257373AEBF4DE2DA1E4DA5E2CA88941F81EAE0E32D982064C8AFDD7A9A600D56D736 +05B9463C6240606B3361BAF22AF74EF89AC804A5793BD512DA2D13F4BB1B73EFCA1E621ED2A65D66 +5AAD0AD228B3B7E3D90DBDB6061E172B686E92355A7C7459D83199040A368B5697DDC3B81DDAD341 +6FF4405E1096B1240EDC18A0E9985CA55A0D697972BB11E9F1BC30765D6775BB68C69704BE200EEF +4E11B78ADDB6229D8FA49A6B1525ADADF17122C0FFF51A08AA7AED158724AC4352EBB91ED0C157E2 +4281BDC1FD610195F495E87062A8C38E0D046DA4067EE16E81BC5F87E583315B973184E474064482 +9B2A52E0D37E249BAB31988B906F891AC904D1BB8901F0673AECE60ACEDE97B8DB7935C6488ADE8D +FD898027424AA85A11A3DA494498B084133B857017A6D507D70A3421235486EB3CF7613C59139FD4 +DCB92EADC60BB6225D9CD0599779217BDAF4813A453989B2E56903F4DBB83D83DF4837C86BB4C3D3 +CCF98F07A23EBBF7AB5687C3E1E6792E40F92A7A466DE352294064537505EEF3F9C308C9EB94506D +B02CFAE289F10005A6E42D2DCE43731A7AE368564B2983038DAD6987F67062199018395BC0FCAF28 +7A2B040C71F7325FA1E9A9808979B2FEF19096B98B8A0A728EB98F2BA3D33B49E3C20BE992822C7A +1BCCA5B4E4D1099D456D8D7D83C57ECBA0FF21428024F7572A1470317CB8CBC8679A974E13D88C68 +1338C68C9AC9557F97784F4E1C8C2E61F26023ACF46232CBBDF3C0BCC5583B935FE9FA09A562129A +8927AE73988DB0F7E733C6561CA7C9716DCA9B88208A715166F2FAE6D5EFF289A9B2EDCE813403A4 +16F243F1B57EEDE7D81E10C2DA4065A3082BC92A38B2457368EEC9C3C17296CB09819E9E642D7365 +F9A6EF430FC7DD611EA5FDBDEDFA72634AB599EB666A5DC178B0A0BD1FAB042792115EF3B6222C12 +41DCE36CB38B738F68B1B3CB489FED9E53315553F3C5C3BBCE40451E47B7EA53FD3D3ABA6CE0AD22 +5DAEE734BDFA3BF1D81C1B42C6D856A05D0924E03F7627C5EB24D7FBEA3BD85716207F961B56803D +BE046E81ED5FDC378F9CA52C14FD8544CA7C539201BEE06487EBDC30FF3B28E8264EC7FD5DA7E080 +65B0A9147344CE28DA5182335875E9F8B2347A44E33DFAA167232A5C3E69E8C5B58B7C7216537827 +C936F5741B87FC68753EB0D4A466961D0050DB59DF3195BD3379F5647F8CFED35DA952D7CF2DED45 +EB442DBFE992711D22EB228BDDF36B8D7DBA27062D60D2271EA8E8412F4290B58F5BE26FF06F0559 +872F9DE4DEAABA015EAB4904BA1F509F6D517C6E897312DDD571D769BC474FD378AF4360E8B1F103 +AA75F48721B9E0BA589319E15D74AC0B03D730C3EF708C7C504787483F134EA6297097B46D2680FF +8AA50B7A255563C88D594B912F5574564A1371463674793E4834AF11D14C7991E7FDB3A6ABF8529E +1A4F10CAE79C60D37429579093DBD041ECAF03824DF9C007E96F45595A524B27EF8774A83AEEBD3A +7134AB4435C80944DEFF5C1CBA921B0A41B9651968581DA4834B3C0E6D4DE13C1E792FCEED26A72A +DC4D9E3903661D8803DDB58EB2B929CE31FC9F50A694116B00AC9F3EEF53FFDB1ACA3394BF111610 +38F39917B022394C75A0D467D64B89A44E5505DED7D9C6B8BA6BA098F140C9C00E09200EB4828356 +A2D6BE9EC1D5524B09C06D9C6FCB5E2808050A339B5E5FD4DD6C2035A48FE9674520901EDCAD107F +67AC8C8E508E6003011978D77ED225F361BC0F86A98B6120EEAFB73F7377DB1E7213E02D12C330F5 +492511B4DDE08558D75D5B8AA2D56A3111DCCD257EE96E3446EF1C76F000C8916C4CE261425ED9D1 +5B58CED128DAA6C1300466E7B152BCFB5E6FAAB2519B8A98F26B29F98133AF886A0AA7E586A090BD +A1DC6120DBB5640885C609A8BDADEEFE5DE0DA5B75A8A29E92515E86E7E66BB29581E5AFF8CB6551 +D8D1103DF60D558E7987E6F56126A13DB2C9A04886C655064E68A0A20D1B7DE24DAD22BBFEE1B7C3 +C208D4FD6A58DE78D6A0A6126EFDEE3B1A9713DEE94069A9F0A2B392A2F391C4C75327803B53F252 +CC9EF0323F84929BA4716C50385681FF5B4ED54929821594F9026B7C1297941B178C3F8A704CE097 +60533DBC6CF4B18AFBCBAD039ECB2EBDC7838A9410E7B227924BED7123944675A5DBCA388B710F8A +F6048B03DFB713F881EA0F3B191A5CD989EA150B979059C8AADE403855815D8F7980CE6288F47EAA +37C1097D33F13776F08779063C5217D7408D9835AACBE5C071EA40C9AE6DF685F4A9827B828815D8 +F3A672E73A418E5CB15684EB6C6FE0998A386E124D76620446907F993BE16FE5AFCEC681F585601E +18182EDCFD3024062A3082AF97E803C47D32229D0A24596CF7E03F18229FA631175699E2F0D60FC0 +9C4F1954C5D12D03BFB4395F0E5EB6C6877083807D91D93CA4177A6B5A8D2AA500131FCB670E7118 +73F8A3C77575EC93A3ACBA37EA117DB268CF10D04AD0F079484DB124F6DC14A50AD3B0294F7157D0 +837D8F9A6060FBCB385606066401708C041594E0396A0BE4B8B66FEA141CCE4BD29366A986ADB98D +9A6935C49C57F8CD415E93FF8AE0DF75E463E02AAC68DF064C1B789B685F84E15E512404E065A39E +9E8F5568A7D97671AE1602605FC7E4933975189837586FB1A55007FBB0E91382A629277C36A190BC +85AF49EF3F0F38D4ADD2B5DEE09916B79690EC83473C63E92CF617617A66DF472A49641DA10654E3 +AD3880D060B02A4A6C75B51E4E9917A2B6D8EFDA12D59DE5A8E222DC7E82F02F23A9D3DBF637154F +719B14114DBB102BE5EB76B441D7E9990EF6420C2E80942C8AED5A1D0B19BCE115B5929AB9E145F1 +496753DD6B1798324F5EC1D0C7F26FC3045D7BB46A14110C99BA07A45EC16002CB754C0BAE7A1A88 +EB387BB345FA70B0A38AB4D532C2DE49274D4F86F2582728A2CC54B4C09D26C0CDEB8FEE6A42885C +6207D74953CFCC583ED82DD7C0F29D35BDAE5BB251B8A2D4B1DC97E2264DCE035E359DFBADDE84F7 +37EA6A59C23D1A64D963E635769233624F7682EA34636B595CCD064AAFF3887D916867475731BFCB +F7F96D5E5E1FBE6AABF454C2F504EA4E8EB382911560195295C87793D5F7739AD7EC7176E126413C +D4D1058EBD7D6EBEE14BB94A1ECF28B686411D91E07373E891F78C4C0A05D2E8D90A8AE2614F7FC2 +63A762D0F43485473A54C31726F8547701D4A38D20565ED1707847AED9C805780F062B847E668E15 +565CBA07A72B0BA99F03FB57D26FA26FF579C30EED0AAB6FEC1B5DBEA81AA88F16F0C9BE869505BE +18C1CB79657D91D6706E2A3F0BE9920655B93EBBAE2B4D0B5DF6BE622C951F2CFA42AEDBF7AE649E +2150FE87CDBF5C2685EF36051080BF39D864573A45AE2648AD97662B1F69787031B9BC43511FB841 +55ECDC3D91E2475D072BDE6A5207ACEA1E0D2ECB1DA8A1BC4BEEC335A5C7102963E84B97BE741C44 +58ACC3D72A7E53B1F08C955F33EDC3A0DC3E7308270C0F7FF814B111459985733C62E8863625A551 +837952F3CBF32ADCFD9F345E14B585B23ECC440775310654DAF7F41E56FF45F89701292019A94BF3 +0EB2D65E14B1A1D6BF89D4CC43187ADADF3F6E03A90ED01E5D876BD3AA56E5EE84DBAA4DAD9824DE +9984BD45AF96FB8A56C010B3C3A3C6139D58E9D69D9109DB18561B55EAD6452497840B9AE90C749C +155B6329716F0152A7AD52DBD0B8A25B9995E1416681F38FDBDFA443879B5C4C25AA29E0DCC07DE8 +BB161C36D76EF286EC88D57C74BF44DBCB4FEFF771D3BD82C8F4E233357C48E516EFE3DB9E60EF16 +8E2C45B54651DF9A5ACB5F1790F7929BCB16CE5E9F6A43919AD287DBC8E12D9F9E97E5DBAA592879 +1A5A02D39D259F3CE273A870906A643CC18D86E23F115D2A35DE6926053D8C84B940B362E7DB183C +4905060316B269223DAD309EB5AC96DEBA757BEA45FA3100F77F4765334EDF3D659E09BD1A5552DA +492BE9174DD406F8353A059ECFEE3709422940A8C369919EE1F22F7C02412C995FE93DC4559D32A3 +155DD22D3526D89B16D9ADDC30CB7ADA6E52D62C5F2DFD142D4D7B6E066671EBAD08F54917E31704 +1F410CFD8A3243F8B39459C418B7B7C6494551C6F6753A94072D09E0D812351D62916383C6E061F3 +5ED864923002007E626089772D269B298DCA2CC1F25D9BE43FD8AD62D554C16AFEB7EF6E5DDA66D0 +5A810F003CDDCFD2C02FFF02BB61344968091F67D3862C1499409ECCA137B9A2A9BE314995B818AC +CDAE27ED4AD583BE29DDE4E8C2400C5F8152C85709AD2A4737BAC768FEB70CE81A92C9657DDDB2D0 +BCF9169D272A063C75C150ADDFCBC2F5F2503DE3D13231AA8CFB396DB38E80197A605F6BC20EFA1E +DE40CF424CF221218D51BEACE64A3DC88377E4F3EFE43DB4F4FC0803BF61764104CFF0B618C90311 +98B094E20B0FACFB94240B438B67BA298E31D3F4E31FD190E48BFCE27B1BE29D36E765E7D295E96E +DCE09094FAC43B87E294818FDE9363FC7DC5EA36A1497EE25762D02DFA00A9BE53F87ABE62E52ED6 +F59818FDFCA643042EC13D670DED1980413950EE43372D31AE2694B83DDA42E1FBB049F7E7B7E69C +93FFA3195A2462423DD2C022E5141783FFA07E192AEBC5070F08B23AEC9142EED56DA74F93BDB504 +78DA55DDD0A9987FEA131E4CCA0EFC51064E4B37632728261369C3FEDACA100F1AA78FB718ECE7A9 +F56296C5FB43781E63F36B0E1D34BB748EFF35E1953941F94D1A9B0FA474FD68B47183F2AC53A63F +9F1D30B9B89C5FE54C3765B43DB403D57994701C133E42B950D9BB1CA202F15B5E590EE75598FAE4 +3D5CF1546572770BBA9A6373F100CDC61DB4E5EBBE0A93E0E51C86005E333F69110B1C8E492F2BF2 +52CADD5B73E7D3EBB53E759353F1EF3C9B8B39C230D13AB7158A5D92EE4C452F81F6DFC18803280A +A023832FD0DCB482CE5AF615C952BC3F7E58F6417D69775FC7C0D5B405AAC632857736ACF32B2EE0 +F2A2C0F3B3CAD483C614505BE94706322F2A2830FC5AB592907D0291ED1873377E7A6158140C2CDB +1B0E27EEC9CA50176102200992308045CCB5A169B61EA0546778B8D280737319046716604945A21F +2A1CB9E15E3A5DB31E0FB5A3B0AFDFDF6F3424B7536D473F9756CA3694DEE4301FB1AB1AE47128F8 +D2B461C051C1B999DBB010E78DD13AFCBBA6F7D5226D540527F17881A18F551B3EEF76A7E28B4FDD +879381A2217EF2FF9F9982E9EA70AD2003B862D7C36D57C5FF9FBEAAB56040FEE973EFC3B34D8319 +1960010110BA10694C17B7635AE03CC1CD087C0B05522A7A791F0CA34022A3F5860B536D9551BDFD +BF560A07F63AA4E687407E5E48584E689591F1B52671213E430A708C06A34D2E1D51CFA6B328A122 +007C81B5EB263B967746961BCFC8772F8502DD95898724ABF369B0877F3313A167F3F714023C229C +5757D4D46FCD9B4AFECD093DCABE52B78132CE9AB6225C9A344C4BF8D96F2C50C4272CB9AA0D606F +013B2642F8C880E08EA2822C8CF5097D2CDB64932FE195ABD5FDF36D3BE123AEDD8BA2F82A8A628D +BE3ED6129DC0FDC4BE50D5574AE4FECC65062E70F4703BFECB35EADE196294FE173EA57938679DBA +6D15448FF44C0D1A903B202439DA93C0B0E612110068F8079219AA89F435E44D0464F54833BEB338 +670BD820D941DF4B31F51B895BEDF833F9C43CB7616DB80F988CE72FD3C12C7D49F740CF85B4766C +0ED398EB837695D102DEC16E24B7475A0F5DDE88FBF2D6B94F126417C811E8362B9CCC52D8891C13 +C10937AACC228D621D4712CB9DE0BAB60EDE2A97E9292BE04E42E6D3425594DF56931A61E1F96172 +6AF6E6891D63B240E6E79E5BF30C052091D681BA1102409874CFD8EDC3EE2BE331676E31AC00F807 +91D1019BB789CA4F5907F4823B002AF3581448C352BB67D80FDFFCD1C5BEEF60523330AA2C045600 +8F62DEB55E69AC2F86369FAB1ECC90D2487954E61117A90D9269A65DFBDF297EBD29C3DD1F62755F +8F289C42A534F59650685F8576EA2FC5D26B99B8E3DCD3F1FEEC73131000F99AA9868EA9BAC0B56D +AE2CF46DA6CC1D18C0AB8D77BECFF7B89992175CBA2E22779C13DB9DF53FF5B1C8FE95E164997D94 +202C37175E562C8622989B075CDCDE173452C064274354D5DB8F7D5A78D48AD4A103B9E47500D08E +DC7C51C1F3CFA7F43C3686A3C24A7EB5018B0F419961564F87E212CE0A0741AC68D6822C7AB9FD68 +85F5D0B2AC249CB7F50E2353CC4B0A6A24562F564FBBC7090C3FDF1284AB0EC615E0B3FBE132F315 +70C8A65C814F93910AA4BB80D516CB70D2E1D11969238E6F022D628FA2F33A0A15C4EF0CE7F753DF +80A8AD9494885A1B9ADAE6C38AC9DA6FB0A61696AD3A502630252AD7B574C841117D34BD20BD6581 +217D977B35F5D04E02B933E1E84F5C090F6615AF484D63265D28517BA74BEA8876FDA332A84AEA12 +E6CD82B94AE10A778CD3A216ABC08495EF319F06AD6FF8ADD237D911F846A514FDBFAA8A1EC8E0AA +9F80F11F1CE615519A4B044F3D1CF1A17D7F3D2174222A5FFA8B39F20197FF6CAF250B6ADBDBF519 +1C525070C8D38220FB501C223F493D80F498621A02EBCCD6EFE914F16B2A435D60C0A1A453E288A5 +3D818FE1EDCA7D55A26A017F2EE47A816E90D6C3FCDF0035EEA307DFB06D2BCCE43458A67354A4ED +B6E5C57233DE4FBE41ED07EE5EC77A5DFADC4032138DA9E1B74428CAD02A913E40152F8063A774D4 +FDD4070E4B8A6C089F199AF7C529C277E902195DB760D81EC655DFFD1BB283F3C5AA8BB58F2476BC +797B2892E94414ABBE96D4DB93E280CF7DE23EB852E7CA954D6682A6F1A4BE0507884C2A05AC863D +2BA73F3B54668397B6C54DC2F4183130AB414875F3C3D8792BF7E5FC4D228DF87748BF0B14178DB7 +E3FFB7891D700A1E9520D778B095DA80E4801F53442D5C073EDEB706A5DB8466FFE7E701ABA9C364 +A37169F585C883A83713A61C9C3BD9336A667EA4E3DB5F4DF6BC6A552BE8D3EF093639EC67E5FF71 +8959F9902477F5AA894ED2D1CD312ED82EE417D95C49C96671B23FB0E1738E892ADFFE62EC1C3D4C +BEB6CD089C98DE8D247DF7ED17DFA2959D3662F105E8386D75AD308480536959F8E6CF8F2C6937B0 +9F2E8137C811327D6B165ABE46C51834A955FE8306D10033F8C2A34667F13A8BA831CCF52C7A21C1 +3DB92F3E77B55CE291F6190BB1D194A33FD73151C3F61ABD2D8A0C9BDE90E796BD996D2D0094DB2B +E98657E751BDEEFE8A43EE4501B98F0CC6D80805189438872A60047A8CAA9039893530A3E5F6BD75 +BB466B25165737C939AFF3EA59BFF4A7DB09C2A5B36B8A1F0C6C5E5870C7C9412589877EF44F8428 +4B8A53B5B74315CE72D2EAFC631BC4CC2E5B71DC958B5A6350CB5F615C3A4502E973622E3E18193B +69572DEF1D02303A375ED60ABA1BC8A179FAA0F221A49078FE15AE13383585FB45FF4D5F3BB3D0F6 +D8BF62E9BD6BAB3C9A7D38C8A5AB0BE57ACDADCBD02B1DC7952D73AEF702D406F62719922BEA96B8 +FDC9B879708E794891C7A0A42F2CCD6812C3F4DB030B5178E3A627C3E77621D312CE4EBE815CD387 +7208FAD92761A5396B67E835222609F823728B1C987857CFEAAE21F2AD5EA9D841212993508091A4 +A2C268BF1D8DA1C650F6AB93995E7C13A3F84DB55748C626FD09C0DA1E3325CCB0BF091E996245BF +51EB486680162BAE63B6513C74CE83B92359938439921950D713C69324A87BCE67B45A030C9CF10A +DFA0A82781D49FF224AC57A23C6CB321F95915C5E14E41FA852F66E1E2044A9E7B1DC3BE9E818515 +D28B2C4D2F2210098C39557067062BA4239F2AAE28816D999955910298A450741947A9A1AABCBD8A +FF3530626089978C87DFC73618C044731B6DB8007739A9699ABC354A6F985E03C11D750B8B9E9AE0 +5436205FAAD1B895B159E2C90562B82A62EA1A7FFB501767DCE2B11C51D55A17529EF5ADF0A0EE9A +96D0E7E89F68E50EED813836531B4B46E9071E84AA413F4135CC882CE832BF78ECFA7CAB0C9F64EB +92C86DFCD1152BB7D4AB33831AA0C139B555967F6346068D5C3351A7A4368EEBD2933E6B9F789DAF +37EF536FCF965C397AF1B7F98AF864B301F3F440B7ACF704B59540453678FD6C1504519481893812 +3E2F47B265EC4F5CF2172D394543D84CD4281165CBEB11349B315A85DEB2D1699507B0C8C110C726 +62EA2959C4962FF093AA5EE6F21F89B3CCB0149CEFEF1855B9A48D28BB363416C015A1F4EA1975C3 +D8807F616C5817C8162536176F464A198EBEE6C97029F15F414275A39B8219128B8C8542E9483550 +7FC2D3908BB0EC375771280B9EBE87E827811418EF93E52EF70546891BFC0FB34969FD7DEA4CE752 +4D9EEFF2B46BED908C0FB2E02EFC1D1624642EAEA1CAC1EB4841E020532E88E59AC890E6C3F44734 +B99722E9816402D1D0FDF8045C5481EC055100836EBFB48E9FBC392143032C909853C9BA38A19363 +141BED09DAF02FDF4E7CC9808321CD0708A1B45270BFFCC3A0D7C27F7E781713D5DECE82C72ED303 +86B02D14575A1A6447547ECC7FAAC1BDFF332C92984758E242256C054656CDD2C45D46E67AEC6F83 +9F95D74E222A6EAE12EFAAB723A7C816D4E42D4ED2725A794743F67597F3DB8CCDDE45BAABC25726 +B851E02E56341EBE69E4D91F2A233583EC816F18A1DECBDA4AB69320F55E730617360FCFB8AC2D2B +737675B406297F7F8C4BC370CB084C22BFEC5FEF02E9AB290282F7B153F0A4B1AE569F1E52371A43 +46A748DDE09336CAD1F5337FC3D7CF0677091E59480AB15021E023E356B0E1BAC6C6471AD53625C7 +0206C338536F4D0D40733AB217E2297F86B593717C61458B6C93A16027CC886A8CFDC01EF19C34C9 +A608B95A84B6A2E31454BC03C10FA55CDCB7B1EB7DC16AC1E93981A46DECD7E7F00638DCAC568744 +69A2D9B45CBC81398727E4ED3DB5DB31965F358D8179CBF934EE2C4D652C9CC211807F070C80E3A8 +222B4C31FFEC8DFB9EE07A94C973462254BC1B1581903EE6F9AD91524A787129A63FCE048B45BBE6 +855826750C586B6B23B805FEC3E7AAAC079576949A06F422FC2C826BDB78AE96135E9E2C20C2B2EF +F6171D610B2EB8635ACAB7C5C5ED9C9FFC26CD54D2FD4CB9E4294E178CECA1E16CC8E3FC06518BD1 +6F4D63AE2B435753538834CDD9D8AE7DE624006CE688938031336351A6578C304C2E5480A3FCB43A +8BEE4953DABC30558B7790C6E7A6F0F9FFA557C50417407AC6A0DDA1E736F7070BC89455FC293453 +3DB004AA9070734C8C2608A07330E421A0220DAB99F8A77489132F6413ADB9EA637F3B75948050E6 +67276A55BEB09D4153DC126BBDBE0DB9298AC799A943D72AFB769BFA1488D311BEB86A907EC9385A +AE4F77835DFFE4389E3D9ADED1B08BBC2B1ED6084B3D1074A326CCBF38E06BD026919107BD03BD9C +30470DB779508DFE0DC82DFFD2DED749E872EB7EB9DDF509D5319865070DD76846C34E4E43691AF4 +29AA40DB4BF2CDD50B275589987D8081F7C5A0461AA5D1455A660178A94A0BA0DCB69C3CEBF5EE04 +26D6534F6F919D9795AD6A0E1A1F452AF3B4CB2EA54D6011FA809132421D111EFC51174E223AB6A1 +3596411A9723079231B050CEDAE7659CF168C39AEA9C6902C2CD37D25492CEE00096EDD63DC7643B +667FDFDE5B595DC54F0A72C2650E1E46990584C78A5CEF9BFC3C5F88CFB0C49CD6CADD9DBA675177 +D601927D75C6902B55AAED0E9E3CB52A577C887D581B3CE6201A1C77C9546CEE5A13B92963337F17 +070E2BF9F5C5E86B84225863874618AA50F4DE855DE567BF2AB7163944ED43DBD7F4BBC0E1623180 +7C43DCB47B2EB694E6FEDCFBE26194D2D9943A1BFE32AA1E5305F5E341EA021F91532162978DD1B8 +C5295A5E7551E2DEE46DC2347C6B32197AF430AF3BB676A53BCA9BD1EA88678377DC0A9A86E2AB6D +E29E3E261BFD5573C66FB5687BA9C0544D894A759866B066E1DB5C66E60AE071CC3A1C4AE40197CD +E4EC723F7B80137619DEDC99AF57A5497D6E03C1C9E672E74F48F6C213A3CFACF2699CAE72345A51 +C71C1D69348DE5BC5F443EC0EADE1E76A8A33066922CF3869E3C1D26A3B34E540DC08EA4DA2DDE3E +EB17C16790DA4EF1A3A76D71D34B788A87838BF2A5A3DB8176F9C097D2320050A79EA6C4A94926DA +11ABCDCD26DBA09FD33F30AEED977E8B5AD928F3967F607628859429DCB4ECEC7DA3411BE35A0385 +1017B535985632639D378CDCD13B00FE537A49FD9EB6DF1E3AAF5C41EBE35721FA6833C2FE08AA3C +FFC3477E7FCEBF9EF9F4DAE62FF78F319481C3F1E72999C8A493EC6EE295316B58A5CD62FFAB62C8 +96E521B678342F04BCE1613CF7F6778CBF5227BA20504500D743270771953ACBD5C6586432F3FA6C +0987BAD33B88BC6C15D29C4B3CC54A9DD72A2357AA5BAEB2CB057CDCE72DC80CC98C62B16AC50B4C +6A7641379B766CDDF990DBB2FC7F9CDBBA755B6E3DEA438FD6699C30A99A8B3178E6D613AA938120 +835E517431D28114BCA1AB745C11FE6E52ADB82B9D3D53A33BCC49740C93017D9531ECF43831359C +5C93CB0E926DB440B139E3125CC2E069B1CF6D96EF68407F32DB517242C3AE0BC6723E560B0F45FC +7F87A5E44E1751C8B7F9F669C24AD5CF16F84FB03BA121B86B0694234D8F2C9C947269AF96FCA08A +78F736E4E04ACEA44C5BAAFDE360FCD8BA6A59724CA86160A5527FD564468123D302DB45173C1B21 +6B01DC5B6D3415B13FBDBBD3121A5493374B3357EFB131CABFE5087AA1D2C7472B0377066B3632C8 +2073C6A846285CC953A8F28E131CF587B35217EE498D9A1DB57B063CE068DAF55D8CC1771C0C3099 +9CA4FDC5D67BE4E7E69418F6334BC6149000821B89A7437CCDF9A6A0ED702D5968F1E04F7E4FE9FE +C9D1E994885CB624035BBC5426CB8EDF0456828F8EEE75BE491B45FAC192A405EBA25CAA4F4C66C0 +DC234D7B417628DA5276C08260BE512B2432256C401A66E3B583E69D23E9FD278CD5F2178544D054 +16B9B4F61A88A4728AF2CEED07C08E207F31D644E8E3BA1E4E2F9D8E30936BCB9C6AEB54E37DB46B +D64F2ECC1021336D0564DF0F18E5A6B6BA470233D8D41FDD9D1079706EA685B6D8A740570BFB78E3 +984BB155C3155C69BCCCB41CB51975EEA1C1B4294CB546CFB03DC31BF86EC3BCB1977E8F94A771CA +B09DE12A82F1D6C791FA7800E5A21DF81C9C8FCDA78622ABE75B54AEEA747AA4F26D563200992E33 +7231A430137C720A17D44F3AD6CFFE63B2DE12D3184BD3E151F955786B8DDCCCB290C42718F3A219 +1759DF76371C2FC177544A6C425CAB14AAAB31628A9CF9D71B5257AFF0D59843989CF0D747375A26 +DC9ED29B66AC2147DA0168306C48C2484C70CA92F33C0C138F92F276F5EAF5EA3082A8A1CB12DB66 +1633C2F71E3B69918F509060AC949FCD52C36498A2ABB77D139DF1EB33E3B846A7C1BBDCEF5DEECA +4EF0AD250CEA9C2751E13EF7681E8FAE0491CFA6C144DBAC1FC39D39E76EB12D3EE9CA159AA77D27 +94F0C433345B135BA632F544082BBDC9471E9FA3AED3A7D465AB7158E8AC97F68B1FBC8D368E2350 +45C18EFCCADEE98778D894D96301F903283C5AE355A863BB0DC5809158F7E108662D04A5C1234915 +E7BD5B4C30F9EFA55E702E54F87FCA06FB321507BC57A1E55CC117E21AA4E3A4DFB77C1A949EFE36 +6D93F2BD827EF8CC16D387CA82AC039F77FE995BE6D9AEFC87F8D809E90C1017803BCFA1C737DAD5 +F1A631EBE6894AD20C70791665E7BC71F21C2C3F4462F60FDE75C8A377CF49BE99314663C6ECB538 +B1BF021B2F2174D2B22CF6FAD115EB0ECE8A2E64097A5FB0A2AF666E1EE13276AEC59FD0C9D4BFF2 +3F71E835984E5EEEE36490C54E077AD7355DBC98BDD37DF29B3DDF8C55480B7349C4D17322418705 +796A8C521FFF920DD11773FC44FC631C7D6E9B420D7965D7F62EC7385F2BE30A51E2D796483134F8 +40AEC71FA19ED1272C27F98F2CDC9C7E54DAB585AC1703ED08F5F9E825564902EFD08EDF99DFD494 +44C21FA6BE16CB8A1B6D0C8A5ABF80A50BB8D055483176FD0AA07EBAEAD88FD694F96FEBD60751E5 +C4D8F9BC747D4F4030BCDF9B0370B7A5E0A6923FF60DEA16EF47F886F10CCEE6956ECF41A21F7C59 +6F3BC78299A9657266807E01762B2B2878E551914CA312C2A68D34CD91E4F5115EA1FBE801346E14 +AE529049089B6B0273E258785773A9CE8E4B6C4211CB7C2767319576758F811CBAF3A3FFB41B3130 +6C49F3798B698A47BFA2E3CA0251C4D90C0B02ACA28C611744526906791D9E157E54CE4E1BCF5B68 +6990BA8AB7897D624EF00EAB92CBAC255AE9177DA9F0D86447D35B452CD2F337147B5D3EBBF2B952 +35778A72914EB3707EA78294B3A3BC4ACB19FE87C72AA1D982E4B822F07B115CADF4D3E7EE3D1BA7 +08653BEC6F0A352A0C33252ED0630E7274961896D461EE8BF523D5911BAC1C8AC763E5FB11FDD217 +4E1F129675969C195476C7A5E18A81BF9A11ED9F2336D5301E3BD32174ED5C933E8C85D6272EA218 +52A6F7E2AAB174E0965F73E0EF89E906BAFB181DBCF8B1F5AA0C12D12C6272753C016AFEC2EC9F95 +41B8757874D6F2E061ABBE8B29281677246305B3C41E90418426C575BAA216CEE3C5EC29B2FDEE1C +77C14FDF940792F48A56AE80AA33E370B037CB28A7373F882022AF378F26B6006A049FD3B35074A8 +65C97D153352ACC156992C00DE26AD21C982C71F0EDCFEB61593BB40FA5F2CEBF23C4FF34A4F4BDB +73CA273C269242D1C6117262B7C47771F2619FE5710855134A80FA8F92BB2425CF88940CA3450F81 +234ABF2B11775929B12CFF86442B2AA0F4243D324A5983E5D1829775B3C7A111D5622D1C4E2B2A2F +982FC8A95F789881416DCB34950A393F4F1720D2212F3D343A17683060182355DE9E4718506D76C9 +184F8DAC55788D7E603CFAF4907DDE965A49C323DFF425FE88C09AA4A4D16283F9B14AB9EF1BB885 +A954034710B4A9DA4C88A8A0932B18D139A687303EE562EC9F656F12F3E8F27DAA9C75DB0FA946FD +0E1A982BB58E040BFC0A49A4AD8CD668493FCB573C849EC5474049A693CBEBD4D79AC7515047CC34 +7A9A7570C90861F3ECFB57B9F53AB9C0D6B05C8C570A8F3C04D58555A45524C98FF091B8F8A422F2 +E0E9E5A7B7FF69F1CEFC13E42F1CA276BCD584516D266BA6838D5E9CA9E9854F50C7D92CAED61AAC +AF758A7C7BE59C3BAA82BF32B691ACA3E8EB171E08AD22C39FBE586A54E6E4DE2CD86B31138546BB +8DA5834B2C6E4838547A1B67E651964E43988C8036931088904BBB589CA901E7EBBC094C0DA81E09 +1915D9E46828AD8596FD0FCA39FF12A6C27A359337F973809E81B2E9E3D43B3146F2516667E607FF +EB9AC80FC95A7B7D4DED551FEE0F3561C70DB2D69ABA96673E39E3397F1C3F8FE5F48BAB8AD6E0ED +8901F90F6CFF24E80CB5DCAC498506C4D01033E497C1241E413B022227A3264DA68BC3F91B35781F +A2D018475C199F43CBA7D3A0D5697B45321BAD2C394B207136E1E16B41794975E8903EF2B2E1C33F +87CF72C325C11EC0B92FD3890ACDF60B521DA32596763BDFCDCA837ADC6F26F129B23CA32F9CD39B +33E64576970DF3C05B8DCA4BFE2F17E6C5678B84D69494F1DBA9FE0446AE6AFEAA1FF245C07916C7 +B7569E6267C42B459435A1D116CEC665B311E404171774C0ACC8DDE96B0D9167C8CC7D99C4240559 +2D745C4428755500EB4719340D2FC6BC215B67823F69FA949C08B5EC985D7AA87C9AC1F9BCC8994C +6CBCE6027B7D1E0C22A83A5DE61DBA05D4AF6884C95F46BA7F253E0B2337E312916E163CAF9DB2EC +56C5425990FE73EE53E42B3BCCA1CF642F02B0C5ABD529B568E9ADFF865B9DC190240AD78AD226ED +884BED3C285B4CB0E3929E805C67F1318D186504D92085764B70DE6AB5AB6990F181BDA50FC31262 +348D980EC76608CF08176C2502E065AC2D8EA5CF9E2D44E2B70A7DDC7B922047C471DF8A0B2087D1 +106B5BD8A830EC0E53223CE3C96EF56E5541191167860EEA58D696EC357EC55799438C90156BBF2B +13A0D5C9EE93227746654ED73EA5B9CAB61DAC5BC690F89C87FECAF9AD03BD39E438F43B81D39E07 +E0422F94E8B096AB38C88BC2E1A043811D8141C1A35DD3A6DBE41620E83C8ED3A379CD80D4F9BC30 +41BB44B933DACA7C5D4427AE94A176829F24B5968B713431CB8BD9F53080832C6B784CEA9B515687 +F121983EB9D9C9CE8BD4FA3BEC48AFE64E643B7BD86D8383D07521FE5D091392BE124CCC91113604 +3824B686988E7C83AEBF406D2DA88FD952D0FA9327F4AD04C55FEDBFBFA76ECAE8A176C516479AE1 +467125B7EB3C9E7C5B103BC0C470946346DF271F8EE19DF7E3FF7478C35EE059297F4BF21A5C7B95 +993BE6202E897776952A7ED0613A5CACAFA731FFC633CAB62963150E86EDAC796026CE02EB235B9F +7A54E0B0C5281567138A612BAFE409A818C216DA8EAC5EDF9D1E3A1E3514AE50735A111B4D2AA083 +4EC6C11E290D58FF340F82F0E079F1C7B3566F2336EAA45BF72BCF88569988DB5F65D4C1E59B50F3 +41E45A899656A0B522847ED567B49CD5284FE50E5F8652CDAC1C076804F2B2185F6A51ED19DD4941 +2E65A0D2DBC844B75E2DF71B009776D9F97A4C6F786EFFEB87A307FB6B912BB659DC2BCC6D509A9F +BDE87DE8D716040A8551B6CCFB7743978AD992D14D2B85CA052E87326138DB196C24593F8F7ECD6F +486F85D1666B9DE2ACA6C7900044EE369D223524664A2790B773F9EA26E0A4CDFD709942A44298B8 +249506EB9B77BC887DC0EF947DDDC7CB3CFC6B48F060DBF032A11884E6C226D9D447A5A458CBA325 +D57E144C6DC295262763E7BB8FF6A0CA473EB7661C12E0E8E23EA37E8AB3387B9E54686F3E57765D +4067E521BC1AFAE52394227793C737C19208803F2F2DA920B553E2AAF94EB992AB17E31B58C15CC4 +AA8A1B444DF5B3E7CD937CF03E1F7FAC63342731B4589F16939D16E8E497A74CDE5686F529E9495E +1603D74875288CF53271DB9313A4511B104F80B179FCF213558970A002E945281BF3AE51E668DD6D +13D9E85152747F562CA0B75DDEC8FE9FE31F8D05B0F59E802888A7A4F19B29954A31108D2F041367 +DEBD6AA1CAD856BDD1427E9EFE89956FE28D500CDC6A0CB80A76902A08D0BC6705583243F1DD8020 +749B257EDF4803BCAA653F7FD6D8B91690995BA5EA3EE92FCD367C11601C6B8ADCEDCE67B16C596C +5D200693AC5FA15D4CC6CE9DF7A71C8A925E99F5085313D60FAD25C1BBAAD28D4AC2B69062D68F39 +0530A976319A3904CEE44DC9451E441AAB4780425440F8C499B81460B5D3E268974145117ED843B1 +71BB14AA84C3A084A7D8E07B9979260675D5CE6534DC176DDB60DDE90F6A3674F67462EF78195F8D +FF74FB5882B079DEE31FE92816F16CE1A70D07752EA25FAF5000ADF79BBE7D17EB1BD2F9BF6CDBB6 +F078CAF97986442680A8FC4121866F9CE86C385DE34E30D8B9768A0136D9EEF79A4B38EE99CBB9A4 +D32316564C9D56996E2595753EA71BEF684834FD030D38BB100E2332B026B046316A53270A96DAB2 +182E994E91262FB03D1AFFBAD623F1689228409884F91DBA153030870A7BEB2C7EE2DEC51875B137 +33B7929041F8D23A94904BD54DD4BC9B432DD0C78DD81639F46D686FFAD39AAFBD1B6C1A37E248CE +48F23E12464D5379B4AED0D50B5A41577E6ECB75270E9AD3EA7D0FC09DAB271FB18B51DCFC0069F1 +5D72546E6C51049F3425AD005F88FD7F02042DABE9F097F9D6A076B30D8CD777B1EC12BD163FDABA +5972EAA61E3C87E9AC007A052B1A3FFE14D7D43C7A0ADC89B1DD4CB4F9C762A84A6C0701494B2D8C +4E4E1A9245738BE4111805C2F153A20ED9FECF2DCF4C8F7C3BAF84D60454A7403D4F5F81C6404173 +A7BA81BB0CEAECFD493D877465DC5735D43E3102CEC57B8A589182FC65A4704661A9E351FCCBC731 +5A87E62F65D24EEB9CEE979C6E10DBCF5C162ADB926EC8CC9BFFE381F6B8A3AC0A19D1631BEA2938 +731AFC99E8EAA39BC75DDB3A39D01AD8F0BC1838F4D674B9BEE9F6F7BE4D9C8BD97E8D171EFF330C +15B76614A1FFD25B3BE19E4A201BCC850F926ED51616318C965AD2F0E56F9433B1247C6D5B72EDF3 +D408A3E0674A509BF30BE813A5E669D72B978794683CA8B85E3469EACB167C30F7666DB5E081B81E +E99ECFBC1704B9646B1A29E4A4CE5654CA8409ADD60145DFC54225BDB8485E39CC98CBC3F38FD0A7 +97E5DFC2099452A2418C6636BD2D5F6B24345ACFA65F4E7DBD2D0AA0C1776A4920B4466C509BB5BC +7D6627946C4DCB38A27098B7B5BEEDC2B3BA18F927077F71E38644597719652037621BB350BB5369 +DCCC073954026E6438FD8393DDB3630C4473F06D9FB9E422E435566C396B12FDCD5605DFEA232171 +CD8EF298786806E9159B84599C26D4C7D8C3BB064665CDD072E2083190372AA808B2268B3FEC8878 +B6420CA829BCF995DC20E067EE6B8E44D2869D51BA3AEDD1763F7F8D2CFB8EC41E6E9E0129DE5343 +1457960CC51D546B10B8B6CE08A1C2B79FBA448DF9783D815608A16C55E589DCD8EF6B04C66232F4 +7A473973A35618000D79B8173258B7365C9691DDFE47B16EEB08B28F881828B946FB5D6FE10ECC6A +FC4EA1F762E90B3320403382E42AF4885B183AA48DB5E4DFC9A54E0B4FFBF7C26EB17A4F13B4BB93 +12234434FFF05549E7587BA0373ACB3E31418BFAF400D8938FC6466B94273D1735306AB912AAB13E +31DA3541C1733E2A7E4DA5B82767D37F3084AA7A7C488CDCA7ABEF77D19E42B4448ABBD346E9BC28 +8ABC4540C0A1CFD0BF46C5BC7454B25E27E9906A3E6CBF678BFECAD1B19B4E42398A210CD567EC35 +FB115D5C0DF0EEECE593982056B0E1D14C292F70B3E049984F8881C8B477956AD3140B4AA22256DA +AC0D11C4126808B5B9F922BCC5F24A77FF352E2C621A3941AC07A20E550A69C49B1B87D116EE6F2F +970918F0F1A501166AC4423FC212E4EC8039AC7F9C212D864F418CBB92948FBD588228108FAC1AD1 +837070512305C110F0FC3FAFE6E1529C2BD0DDE868A9EBE5137DFDFC5C12A3D08014BF0EE27B1080 +02AAD6B607F5C5C0F1B1EED3C552919C9A2E97204A8127F97B1066607ECFB47BA95EF2B51F007C29 +3B2F6A63041A9C1120D9CFCD5357222E5B02DFC73CF94CF9B5CB00EAF073E9BF253E30E09B50341E +57BF245A746EA31BFFD0B00201C34CF0881BBD1006BC9BA7D420A48E53686B598BEDB3449924EBA5 +8D5DB1B1B01AE2BA281D5758C99EFE38ADCE18F7B182FBD0D0622A6EA497A4E7C00C7D17299A2765 +EFD8DE376C214D01A21819451FC04A0277EC84A151FF93903D61C78AB7886911E36E12526ED855AB +43F6289C1890222602B8EFBF15782B374AC1E580B6E963403D6D15A051DB8558F2E61C0B9476C6DE +5D4861585CF515CE951732F20D32969F39192FBF1690D242AC04D47E0C53D467D0FE4656B9526C0F +7F852348B0437737CB0F29ECF9B54A5E17185236DD0C16349C3496F3ABA569EA20E343F6D771210C +39DC932DC65ECEF94575C6E76902CDF6C8C8361F9C757A2577DA535187FD526699917CFE0AD438C2 +A758727B306BC7979547E68B94E87ED820614BDBC649D469EF6B4E4E3DD2EAEB5F80B22FE576CED2 +56495467C76A75F589460061E03F3A1B065121A5ABE3E2C51148B3DDC9F624C97889AAF7FB84B158 +C015EDA5670746C6359D27B0C2BD65144F2B88A64331816DA904572BE398E015A9924218B3EEF951 +23AABFC3AC8217B7B4F691219A1C9DD0A3EDD5C04E63ACBDE71B423522532561F4B71B7028415C34 +37E346BE728A415596AB749015C1D59BD8328E39A850CB98085B34B57FB52DD1D154F98FEC49B3AE +BFCB1672762E4D2A1ECF02787F59DF1EBF2625C3631BED849B298C6D226BE4E6EA2AB66A287D2BA9 +2A6C9C612A5F849B3CB3C25F17164BE286F6E4F5E7E4C9EB17BC68AA5EF0190B64696A570442E1D9 +BDD1A30E7692524E30E4B4C3DF84481DCEC6E10E7308E65DE9D90099F3FABB3F4F766BB86CC98594 +6D2003E21287761A7386CD8461615B570BDA015F5EFA23D18E83C325EE444EC166A1A32D9818C2A6 +5A092D44156C06D3FD079B92450B8A491CBB3529DDAC7D95AFE8EAF33777FBB265FEB8A4B9AFF2CE +CEFFF49AFBDCF6C4197497D3B448866D70EF28D8E4B17E7CE95F43F64BB48C4A73EB84B26650F62D +3E5199D64DB0B5B87702650ED0B850FD5D16C848D096E4C7E61BC63B2A3ECFC099CD713E12C91A65 +77A88D6F55D348617C7A49890A86EA8FE2045704B5ED529DB128C9B19EE129E5FE6498CC97087F6B +DE96007C9D01CE9CAF75646E5A5B32BFEAD9362A52223D746943A2D09C536CFAF78E601BC2D2F0B7 +63AD722E3A7AE7069D65F9F2BDED7278511D0120F5EA071D41A69F8C2A2D720D3B24B4BE61C83FFB +EFFAE21B0560A6FD1A44E53E42E0D10E0E93F421A8A7E167BB65F0D7F1DDE2809FA3CDFD931CCC69 +B119C83238C1C00EC100D8E7AB1C7FB02EDE97073C8A5860371A8132BE391EB1C397B61F93876FEB +438C288EF2E38DDCD182A5CFBBA994A94A1BF818312CD8234215FCCD7C240A15AC01A885E1179E5D +7D6305DC2F534BAA141F25EA6A5F356486E5FA0AE3C6980A9F5E8E99E7AE5B95AC42977510970245 +4FC951E4319AE4B1DDC9B07D0998372C0A95ABA6985A4DBE6DC633154FAA30ACE689D36A7F17011B +F29CEDC58A6692A8B3B0A5742E6CEC2F69B255BCEDA762DEE72F125EBA98891CFF4D88AAC14188A1 +8D81424979C9079E44890D94EE094D4CADDC1C7AC5F6791FAB8849CC0240A579ABD800EFE3AA4EE2 +F78119A3C2806C05C2B1F17940BE73984982D1C0065433A9BD658EA31AC819DA9A11B87475BB565C +C294B6F302FE3F7752ED9B963C5279B5F1196762D0E12E6DA46FF9A0CADE3876D7DF695D8965CB4B +47B351FA3F759811269376B2C3134403633FDE27C9B024F6BA81F3E1699CF64A426618428BA6C326 +6BF016C5DAA5FA4CC82FB6DC23FF2D742160518CD3A65ADB38E53F1067076CA1625466E0C64670A1 +564A54CE14DC5C57D24A12283FBCBFFD0FD594AC2A56EE58B552F7586825E4FB1EC23F8221711692 +C8C56F42272B87EBFF3865191F1C11943BB76D8C0CFC53ED452AE49404D2C8193ECC2A7BB8CFBF24 +870ABA38D2CCF7869E9363DC0AD94FACAED5922B324DC3B6FE83E7B34FE29ABC1EAD62B49FFBCB81 +1ADBB5148D5AC2743E3A058386036FADAB6FF071BC1C3B8023F908B6FF48DB0AB1C9C67487C35211 +D40995E1892C8B66AD6C9C6203F6F8B513B11117B10DA8725AB45B4437B5A88A96AF3178D856D601 +196E8162868A83DA64E408FDDEBD14D6591881EA652032CF2F88B3FD6C0479C8F89AC68D14D01AF0 +CEAFD95AD146E68FAE01A07F39E7A0C5E4FFA6D6A91D710827CA5ACFE7D1F946A8D7B67621D60F53 +41F32C12A6EFB03AE5AC5373A382C044A276F6B41C173D0AAAAE0C1DE4C3CC71EC2637225CCBFBD4 +5EAB92BF39357C57195B410F74283585B12B926438AC72AFADAAD2D0FA2CCA728C8E86BD3FE75D47 +B8BEB96AB13B5480F7A3D5741EB51E3E40C21FF2ED7D9221D9877C7D1A8CECF394E4023FCF8C4EFD +B38B839499FF5CD96A46AB4FDB46F35D3B48B91757C0159328120E93CF1F2739E936E28908FB1947 +1D3AD7F6F1AD2BD1EC364986A411CC1B547D0CA104FBC10B1CA7B638A60E75485574034561DB345D +DA68415146AAC632DFA34769B6ED7D7D4694E92CBFF4EFB16B55495908102E85E827FC623CF1BBE6 +A13CBF64E878E1A2A159948B5529B75E071744A5F0E50DF18C110B0AF117CE7F33F8C959D4C98CED +5A9D492AE6F56DA57B0F17495DACB130660BCEFB064FD8309D965ABE8D2BE98F6898C1B7A39CBBE3 +E75DA0FFEF6CC3945CE76DA3BE915546FE8A5310130AE0ACAA9AB73C7E041C00533B4BC7724657AA +649B9388B791AAC5EABFCDDDEA2CC67A0FD0AE9BE37DF9AD40636538EE55A83F60E9E026C64FBD8B +220CEB46E67410144A520FCEACA252E8165448F84D8EA083C793AD09B90B3EE83B73FEFC3365C729 +E3C738894B8C01C2F8AEE0CC8B114E1175EFB44CC4C6CEF5C8754B1CC7CEC200AD8BF1189D741CB7 +5BCA4E88BE959E32216AD33F674F49AB20A354CF3969F1611A95D3934E148831AE7C81A7EBE3C524 +4F743E66A82E10D16CC09F8194EA7A596BC5981D833318AB4F7DBF2ABCE543E410B649D18D146F01 +486159683DF61A3F880F9B21EBFAB77E908C6CFC79F89BA5F51114F0BF7C3CCEC7BF0F3B057C3195 +CFBA6908E31E0DF10DF69163C9DA7BABC00E9A580FA7FAC202910615BD479BBF76FB8068630D1EC2 +1CD2926D351E869E16C2CF1E023CF04D4FC61607DAEFEEEDFF5593E6023492F00029E2AE4B4A2C14 +50954EFA2792F32B4934A768F892171245A1E2F034E2B9F39833F1B331A19A386BAACFEC8C929BA6 +B67CD8922BBC9DC005EC3976575D5B0508D0717C6BF11123EA36D8FD37FA77A6F1F5AA84D4AD8D25 +B2C11D1877A6E2F9B74F3B5829FAEFD4F7209CE9785AA6FDE68672554A6F29D8BF03FE108ED90A7F +58690FAC399A8AD3A26899072B832874DDB629581A51B3325CD9EDFD49E890EA8959DB937DAB83C7 +77F2A426B967AF5888C33A3635B78D647AD6BA441E222C958EA58D61945F781D7EF409771B89B202 +42AD7D07C2EF592CBF413C5FC89EC30FC9EBEE4BC63709AE33B65EE3091CECBE610B847E12C556A2 +79C8B114C3E460822D3330ADFD72BD69F54C08A81848C2002A08326CF3B09B1305490D35AEE59179 +08E1604ECE75BBE811A715AE8AF7EA9C371B322D0428EDF4C893FDEA607E70E1B6F6614947326101 +EAEF18E29BE0557D2A92CF1FC1505E8B434BC368CE07CCAABC0774F8A63E1073FBBCEB3F4052462A +A9008A1E53F188C9EAE339FABA74AFD6D60F47282CD9FF721F64BD51787F3C13B5A6C5A5F7861171 +0111F5E0471E206D72520F1DFA465F4A23C71DCF99A04CEEF11B0E3BDFC35B7461A60753D3AC26DC +50A5956C9195A4F5226388E0953DDD03AF128A98F03BDFA0602CBBAA20AB9ECCDF7255962A332E16 +D4380762E498FDA4885C64FF5F9B480DA487C58E78943DF62616E6E2C69EEC8836DFCFA9EBF58938 +A878F3E792E8BD8C5D6DF557A5D82018DBAE1CA9C64BA5AF8E21BE1B6680FC5DB22422220B776E9B +A0BF1ED2B7212F8BF111EC8C8C77B223C05EB5E5F1CFABD2D037F4BA0F9503E2CD83F4519D180476 +63F09E308883F5DA5228F83045FF41214D2273B2FE0A9017D5E0557BC2A198C35D1E7E81F7965444 +5760CBA1D3F05EA4B90658E53FDF0823BDB1501ED51DA75C47395073D8980D1E3504E3F67DB3259E +4EE73A87CFD96F84E221796573958D364A51E635FC55478C9CBF9AEA16B7D8C25F2115CFE4B7F598 +54E24968833BA0D64D1D332A666DFA2A3FD71B05A26BAB7DA382907B13DE0B80871DF184D3622B62 +3D7E09BC32A4F6EA2E6DA450A906EAD36D53FDEC7F83E101FEF32F4FAEC581B000686D86A0D3861C +1E67F18A4C4647F51F978484D9E3100B37BE9D20AE84C085461C1FBF929C669E936659050C2627AC +1B019837BAA75757F5B0A82E8AE9CF2111931A38BFC94744E2FDE3F8710342AC615286E4ACE7F269 +743AA05463AF537D9416230ECCA859D8C99B7C6E70BE7FE11DB698589BE9E11900C8E9582A4EF5EA +94B5F62820C90DBC022A620EC536E06CB8BE7526A789996D0E741AAD980880A33800A6FE92286CCD +02C9CB407EB31FB95D9C9F4AFF38B37087AC582C1F7B64A7C3D2202BDD62E9AEB31BCA85C4CF323F +03DA9D318B91F78FDC0D266630F7444ED068B55C05461C97552366A82C2E743CEC353D51028FDCF5 +403B3B74D379B82EB69C4380ED40239E15A86B2E5C860891E26781CC111FB5705E3B7C7AF1946006 +54B5FA1B5FC54FD0BA43666E7BABD2C91C859F393ED49F7123EDFB648A3D6152F2C17F7E438C0A63 +8968AC06B4FB3F77F64F358AE063820BD33F0213C85C40E4D97ED100EC2DA1C2E1EA258BF107AF67 +5A9D995F60BFA37222B9C2B325C0052BB8537D2B27DD43A129C7E8FF42757B3AC9B447703D382108 +DA520B8B3BB3E8C7295B776B44ED28F863B8E1F81B0BD1DAEE8A171525D09D2620C04DD3219D880C +2ECC79282DD7B1772A9CBBCA706909AE8BC7798E6EC7375189B6CFCE8A875849176E5913B85A18FB +197A33CA4B5B4058603CF1FA79A56856B43D538E9ECE117D99AFA73B57E307364F553644DE01EDB4 +6234EFAC13046B6E047ECC8F63942F20097AD7ACF0A45C0501A95263DE9439A880D6B5C5214D2918 +0A54D7FE9B2E627EF49E189B59FCC78745E878E45B46C0A648955D3EA8C935113D94F92EC963F66C +F3CF3A526BA71CDF3CD4CA69EFAB08B7389E3390716892A4872BD29DC1E0889A42D7FFB4190E9A8D +05D84EB9C5741BE6B02716BC75E0106F5F94BD3778BE985E03860D27E44088C3CB2A059DEBC420DC +E3A8F4087A9548485E616C409AC400DD1C411CE4B6A229D091B253EB68F06E43511EC5AA6ECA4D6E +4818D6AA2068DA1AEFCA377611BFA816B5215182432D5683294D67A7C1FD76C52233087CA44943EC +7280005E93145F5E7AE50100C18364E1B36741E9647C4DC1F68A58EC44095920FDCF05532F603717 +80F78420077EF5C24D63E26040CDDFF8DFD65D871DB943F50CDE84900C1372EF33FD8AB9889C82F9 +4F61A0E6842219A0F39EC7B232CBF802C4A744F33159432E827006C7CA77E480A48A9B0E6A876158 +8A3102E3F98A77BBD62A3A23150FD140D3941773BF7CBBA2338FF37B9EB640558A2313E8824E8E62 +0331568A9B76F4897198A709F9313F4AC40827D8C3A71F2ABFF02BFD57D30D0B14012FB5C39B85AF +540DDA0ADC27A85B31694E8D7B61F9D9B476571022D98F2D768246550A877293F3FF6ED918A498D6 +A600223E1A61890C49ACFB60265867CE9464F9C32C59E94F7641C3873FB4FA6EB237F8ED94579957 +270D6FD640BD9543E683F2372CCD7B60AAD269E03A72C5CDB732B128818D41A6DDD2BC139F7D3911 +F48E1B1D263DD4AE8E4CE1A686F3A00A2CBF48978631CD243566E22E68F8D7397134A3530EA3745E +4F1EACB4D6A5FD84C3011094F37573F7F9902305020C53926716D4780C6B0A257BF711AD94C83F1D +41A02C1C7DD203A3E6E4B14EDA2FDBB36B063A3E074495F626B0EEA146D22AC33457F44F41675967 +6D2A0566EC2B726D2F0540ABF225339F02F406D4E7A62E5233DDF20AE7C86CA0CDD561F33C422654 +BF2DC3685CA91BB9D4B09AC8B15A24A99FF56E2894F11F7BB4728FE8F0F5B799F74F475D2D01F61B +7E9E0E541F7FEB8A557486D7DF2CE50927515D833BCAA1CD9BF7A650BEE9E003A5951C98ED147C4C +52F64F692AB281984EE65A47E44A4A5FA93D6F18D276D3B01C5E5F6135AC6940524CD713DF4077FB +4943E8AC927A68489EA52ACF7A854393CD027EB52EA2DC6234EF034F3DC742D6DB5A67FC21D22B97 +146B9C268BA97C30161CE01EDC69A6A1F05EFB0E06F22644E1A368F0E2C0C6C1C832878E0614B74B +D645F5CB293CFDB7618B837FFF14A1210AA061C8C81867244305B80DAA73CB25A417228E9559E7BD +52C119B0CCDB7C4DCE7E1B9F7E8EBBCB575E5BD213BDD6DB88769DACB05E5870232F0EF82F448559 +187423409EEF756BA6247493BE24CB1879B5DD822E03D0ADEA1EDBDD83D3FC46759C679B921F0616 +F27212903F728AB44C1784E8A7DCED0DF5625A7D3F48A20FCA34008184CECD145CCD98E31B79E174 +CF107E8F35C40C19D86B40BAEE6164353408801EDF75A619FFC5B6FAF3F3A95F64795CC40C1F8963 +4FD8C13852D265FBCEF834C800AB46E3E8167476B23CDD8AFF6E2F997C99A86A9CB30EF8C853154D +0D89EEE9B9CDC1B4F27BDA32432A4173B55CA8D9FB50ACB2D886AD8E5862FFD5DFF224BA13C8B8A5 +4A7F1A9F987FBBDBC5A3C3D762A5BE309D5D926AE5093C40AA47B3B1BD828797CBB9BC9FEC9D19EE +A73D2A39764816113A8EDC6CFA6E605AD578FC8E30ABD600658A49ABCD5AC54655D29C50FDB72070 +169D1B389F114B7C71EF95A80D82AB537AC8C165D47371FC142A51625029A990A577EB1618480D72 +6DA93C98E5C5F24F622A850CDD94BADAEA91D4BC32CD50CE69E9F00E77DEA8EC1D37916398FB7092 +402605359DF08AFE7B99C76C2A7C70383F28A7C000C696F45291BB8F074791798197CAFF1544C76C +EEA8C9E6D76EDCBD92A86DF889481F3BBFF0865442264F0EA40D3CAA69AE467A08003F9C30FF7F2B +77E767580575398462D5B1171DD441D8986F33BC7BDA17D413EBB6B7A32642E33F20B284BF3EDED0 +02352FC66C6F7741A542155F4A159CD778BE56B9492CD95115C1A06189A216CFD2E6725965A13DE9 +73765A05114D9A5A4BE0615AF8BF6A5EAFF84468B849954D15BEAE1CDD57C435788B331905C01421 +B50F20B184506A0BEF746330BC98E9C89AAA8F9D102F158043BEB6A682059A1C8B8CF67B2F3D7AF4 +D8BBE086254CDE53765E3226BA2F95AE8063649F9F94BD9519411DAF8A0287307335668190638806 +E29484A4FFBC1E46B1800E03B162C23B1DC0B4C0DD3C7ABED2F00762972EF06EEB9BCDC7B3F39C70 +BE32789D366F073AC3280C273DFF2979507671B3E1E7685A9A4F0FD3867F96DD675BF05F25ED986A +79249B75F182FD73CDA2A6A66D693E4CC5AFE3402431B2C816DA1486C34BC9DCA4E2D51C868688A7 +787CD10ABB9ACA14B7181369DE89913CD8FAB58FC84519EA2AA14E54B7A8CE474F213E07CF2DE2E8 +88093DEEC937526816B71C96ED75FA9E2EDC0F9E6E84569C12BB8E39AAEDBF546630745553D6084F +F9524FEC6A7264F88CEB7EC3358E923B392474E3A48865564431662988FEA768CE555AB0DA48BD52 +6A84B0CB17B4584066C1640C1023D91F7869EF0C4D701BE121A6E3C832010427490758AED7A2B30D +6028F2215AA44E86D852FDC67DA5CCBA79EEA863BAC9EDC2535B66AB0E54EC4D4411390FDEB8D1FB +C1743F15C3B68DC92A8659E7A892D5E53872EA51EE8CA7EF51103E87C29A2714E907C79DB9CF3744 +1785D2F73A1EE58550111A4D9BCCBEBF2E39CD3B93DCA300FAC3ED1ADD8215301E5766C30C8CF296 +75746C5A77BF1FE3CD75D25CF193DE8D9AF02AF8F7A6E8F84B548058CDD3C6998ED13463FADE7391 +26D83D3CE2C7201F955382832E32C10DCBCCA35835985B9A93F8E3B0208BE6E92428787C47D3808A +0F77B8F1D76E6BF6A17FF81CDB065180E03809D03638307BD7BF5CEDBF64904E918FC805AC905379 +928B816480F6E3BDEE47042CBA98539DA0E113B1A5F23EAF1A3210BD18561985E6436EAB90395DA4 +77C7A6D7888D2377B3FC4169368357D880CE041E1F7C875E956600DB7D9B35D1EE66BE476E9DD806 +4CC02230276829C2C0A098F051502E828A0CC505AFD8C3DF293DA1508AC4D25866BEEE6BBD5A230E +9C2DCDD4F06883936381F476DDCD86CCFE15C2CE3C3243E148CBE603B8513A7CE7A6910A66A90B70 +89E5CCD4368BEFFF2BCF8E918BFE0A1B069AB2A914CA7BB91A0AC3B3C0B060FA1A0316F6135E890E +E549315897C8464496CC6DEA0F7E3AF43FFA4C3281156067582CA255B1D2E80F999A3AC0402BBD17 +01824C3BB524130F5B82A45275807BC2F3A0655EA208F968B297F98C369192C8ACA26BEBA7DC4506 +FBD1305E2EFA4DBE5375281A88EE2D6FC88FC0A755E72934B4B58F6DD3BDAF7171A4A3C776576735 +2492BFA9A7758504750AB7F38754683B70E9E293CB1CD7B23BA62BD7397ABB84D7EDB22EF6C3F58B +3EEAF656E361747ED04020163253D1CF3F905B5E85F83FFF30AB2778CAE43781667C0F65C8FD404D +6B9202A99EA76AF9AE1236631550B66B063847180B6DCA832EA8DC4A6EFDB674B5A26552A7C7D54C +2799C7D4E03C24F661A91103086DE3A90A774A6988347656344CFBA06065AB22476BB09FB68F9928 +C0045F2764AF643CFEF0516D87FDE6DBF93BAE2829B176CB507BB99835E01BAD5E55C2F8798C93FA +35EB3FEF02CFA31D3D21B030547F86D27B9448D68E2B155A65C742BD2999DAA0C3AED64447B9CC67 +F7AF33B63AFAF25F3CF7EF86657FE8F952288CA4B691D369E8F1935CDA44A180A6767560C2ED3F2F +CC38B6BD7991D4170C7C566D690A8A25BE03212A80871108D18CCEFF246623E653107631F29227D6 +4754B2208D19F84E547799E691CA473780DDD56AE620CD953D5133D135E3D51F237078FEEBB73714 +54EE633CFE238AEA63F9999E32850E6C197687A0EC4E5908D2A18C5349627E336AB5E3185B218228 +603A4B1852069F5EE849D571B8387DCE1F8F8E9FE94FADEF128BA83BDD245F8C1C27C11F2ED1A8AB +2D6D601726842CEE744EE7AAC6B6FA16CCAA39DBF5B3B1D47339F31DFA562671A9CF7DDE6915FEF9 +F19B3E068A464DD350A3AD146D1A241673B5112A4A8768F976723E6E184790C0604506C46591BEF2 +106C40789B733331A80740D59ABED39868F80BECC2AA21C400A0BD0CC326D186FFF9EB37680F1EDC +32AC78F9059280D07B5FF2E354FED545129FA5FA8F3D4317FF21E027602FDB2522F049BB545FF4DA +60248130F81F4E348373142F3148DED038AFBA818F26D5B49FC02DE9800D894E9239C88EE0EDE431 +F8083697CB0BE3B497473473E5714717C914A1A926730C249413FEA2615EF72BDB0906933387A892 +370F77EEBF62D26CD583EE643B02E323821379C0DC966407D36AE3CDF646B95DEDC7D7FD0F28E950 +78F12DFC0D6400B327B743C548A0A3517A175A7ED963ED756B1E107AE7087E2446BA702CD4E26E2D +CDC1A8B697108B5B5E81E9F03105F220C72D4AEBC57665887C8C7964089FBE9424120EFDB14D76EE +F8C6F7A30B13E1AE90CB9D93D2E14BDE47F4A1D05ED5B18D32AA39911B92D24C93976ACEB7EF597A +75161923A73B2CC761785493D0EEDC08B5AFE95F3C006B41438A0785C962B070DE2BD096CB63B847 +C87539880AA3D3FC5C345E0992D7BE77C6CFF4948617FDDA784CC55652192B0ED775129C4EA4245A +41BCF3875BE319DA0EE2DAFEFAE920CD2B6C6C2001762F88C0C5C05053025C0349DB17104360FCE1 +5D7F3A8E30ED13155A74FAF91DC77B8AABDD6FBD5A1EAF255DB209D7F2B90822296B5603FB5E2CC9 +5CBC5F7A6044058B8044ADCE73ACFD896177F1F70EAD2F6534DC3AD755AB2BA87126D63CA2E9C441 +DF0965BDDD6BE494E58D6B5057A561D1E31BD38E92CB73C1465AF6B9C001F7229059BCA4104847D1 +639E124E082F7364B56548BF8112D0EB461B316B2449049F6A476D36D6B7C0C1126C08F2E9A1246A +3B5B21E7C8FAC6E23B82E33A7783E4F31F0240E96E69C9444E7D7A928636CFD086475DF1E0A28464 +81387BB2010655B9F81A0744121699B4905AAEDCC84BC5D5AB3674601DBBB651EDE7B5DF05C8A463 +DAB41F79706D285C4F9063997F7AC8CEF35CAD51FBE5F5BB1B3FA6DA2C3ABF2B3E925581349728D6 +DA0D59C1EF6444539742EE9A23A5727F20CF9377F4F84DEA420607015A30FB14632D084A2DD181BB +02FC3A84FC499B318156B675B9CA3CCABD87FDB2497C6705FA70EBA43ADDB6CF961B30E8F6AB9F84 +E1DD8D6DB3314B34B7F7AA3BBE19D5BDC75ECADFD8EAE19E07B387A1FC586F0F30DB695926764B54 +0D89F1D854B0FF86528AD9523CAF56371E29498C11AFB2F4D5202670C834E930103F039D13348824 +16A49BF93B84FD3CF1209EEF7D4994C8302436C0794497461C11F5B8BA152BACBCC08AF8A15F4A4D +F3EFFB7227CA97FC21D2D0356C93390C749CBE9750B821F1A7BCFAE2C8BC6D9A27F844D8AD088320 +79ABF0EAD8ECD4EA72846DFEED021857F33C1ACE4C07BEC90398B629814C498D33BEB375B9A53DA0 +F926FE6E89E70322C72CB2DDBFB16B13EF7A4F50DF783316584C6AC2BD7D9029124933133B2229BF +74A228868AB30EA5C3E87C78C3F0962199480DBCADBEF53BDDE45849DA857A4FD85B96682F1EDEB8 +5384929DEE4AFAF84C51A09F5D572705673D885070303FDB47DC898F874E103A9E7C1E894115DFDD +AD81549C7375D4AEDCCE2E52C13E5130B47F206F7C5AFAF1F9EE83DA8188D70B473269CA280A6A02 +DE85300B93D8A4F6B402FB5DF58F1327470CE11CC63ECEF2EFAA396A6680A6746A20382D9529B58E +7CE684B39AC00F7086BCB47C2230DF0343BED9B9152A61C9826AEF9E00A1452D91305CF05490D4BC +0BADC9C6FCBFA93FAD52C3A80705A1956890497557C0873EBDCF61CCDD2219354A4F5621AB33B119 +32065C1D990A9B68858331EE7875CAC855F98563B14EF9E1060BEA90F195AFFF94728AE935453438 +DAB35123D0E2699475884DDAFC7307A5CC06920F35341728D85965F5BA86F261CFFCB1E29B429F97 +6970D42D10E6AF6C4B792B4384122AEF2448E22A58D3AA007743C71324EA08D06819FED14AC1F22A +4F0BE4787BC8738E1CEF240677571C65804ED3E748D72E89C94B6F310BE748FAEA31EE246859CAF7 +A1EA17CCB5B246C87EAB771E2AC5D378650191081514DDC2C66878E3766CB20DC49F630F2743A7FA +ECBE9DBE9E815A3CB57DADF2BFF5EF2FCE23A56298A30A2E052FEAEFBD698101F9DB992613706693 +CB0EFAF6F60C8BB5E7D0A50B3392B9831EF3A304A846CD4AF431E9F018FCD3A5B16387552D55DAEA +683D36257418AAA0E7BF8A03ED7BAB114D7C15119E6C71C1946BD7903C1C42E115E954619051B853 +BF05AE316E15E619A7DEE498F771E809D9435969C1056402725EF40C0200E083F3EC6E0EC27B8ED3 +8DFE32EA0E5E156AC36C4BB9AC5ED111A11678339703F1B9299345AEB1F251FCEFA11FB3101CC499 +907DC862B4463D5523B9B25C5B69F70AB6B29CFC1DF1ECAB8227EB3ED1F882E90B12080EE003714D +403EC43B7B54491446B6A3DD6EB641EFBFEF060C45E873E7398025B1CB7065441F1753028F6F8C49 +A96801C0D598E098EADC96A21117F817B6FD6E6947642F93E22425A00E8F6B592AD50B317B69C0F9 +4047386A45E5EBC9504FE55451A01EB29DDF9A41D4BAD85FC84CE280971E834F06CEF49C8C20ED2C +EAC889F158CB14A8C070900478804CFF1D1637CC880C81AA287D8382837FFA8F41FF3C9DF2F22CB2 +0044C171E4815D0D0F6C22D19A52114E780CECD71DAF63427782E85E463DCB333789F496340E8CFF +885A9D9A4250118B439C71C6BE51A9338BE29251AA794EDC67DEEC6337FA63CA9B03C1C9F75E733A +4A918646E7BC9792486CB5A4BCC5F84FBABDFE338C3792254A3EEA3D88903C2C47B91E076259DCCC +8BD3DCA90ECCC832C09C45141C6242026BFE309029A562C3EE0FCCDCD40E5CF265ED9C3DE582884E +0E14819DB98B3AF734B1B3276AC41D43384EBE73003D15CE39FFCC04109583390E470F431B4407F9 +8550E138F96C4564B494E5480F47C853BDD237E27301F55E42A3BED18FADA152572B7B465A581DBF +E7DB2619365CF16D71BF8F091862B9FCF04BF8D0859A76F46E7B5712F2757EDCE332D3213B8A30AC +2CE7D7797EEF6F30904906B0805DFA7CA36D32A20D989858497A66CE72491393DD79332003D55C09 +5A5AB5DF761C4BE5C041FA8407263D604E53091F7B6B15496245DBBEE96A63F10FC2978D99E65731 +28689366FE8B0BADA48B50185B861BAD03E3600F22BAD4274F2542B635F6C7944BEFC3BC741BDEF1 +1A8DD659038CB40FEF2E16AD1AE7EBEDB7D9BA15FDCF26355331505A386DD7399FB999535D6061EA +BC61DD76EF3EB457446F29D0BB6EC2FC0AABAC20B27A3C123C27BC27A76336D0A0A6D456DA070367 +4D959A4AFE428E2206A511BFC80039ECD56E75F69786DA0A8084D81A66644DD98B6018681F1D70AD +E09BD9BF3D16D68DD5D0A03AE26DCF1552549E459FE190B310A8776B2C8468C14CA8B1B9A7AF2956 +507A3B705AD75A17A0EEA7FE089273353CECD07BB8563465EC8DECA0EB42F43FE3664EB5F31E1D13 +24185539B28D508BCD065ED576D8814ED3FD637D576F027927162344AFB0255A91FFC616948E4E35 +8867E9FC76A9AFFACAEBFFE110808C1532A2BBB0DBEF3F010E45FFC73F228D28F12E98478B27397D +8F456781ED9E19711DF2E9EECBC3FE61F7493FDF1A59124668A91BE51F122F93DCA4BBD22DEEA339 +E6EDA3D6EBEE03DF958113E1CA49C8398D2C59DA6764882EE3663F62A55AE50A7E91B4FEAD1B11FE +0D50ACCC5D75F1A515F0C53616A500F1491381DFD0E2477E402AB0CF9F67D501A442629C8593ED5D +25A72EDB9746B02F2B0F0759CC9CDCB4C9D8B4519C8C617E569B432F0CF6890372AA879CA7DE46E1 +10D95E230A4F0E52CF65811C54365DF4A3E40D819E2FD379B47DA3233D0DEF0EFBCE04AD8BAA3888 +4F6A69FE5C373E38AE0FD0241480F2BE7CCD18AF85916D2703A049779FE7398FC47D348454CF03F2 +2EB3FECC064606957898B5643464845445C25C0C7D685C8DB042AF5D5882174374ACE90081C68678 +9BCA96AC602EB41D317BD652293EE628951875641661EC86A2C40A42E8F0813A861D41A0F5178E55 +43651CA0E99150462DB5EE0010F00DE6D55B0D7FD7EC5BAEA24ED3E90A7D6A0589761922B91A6A91 +3A7FEDDD3B68254D89ECF767CE8E27F966426A8B4FB1B4085384FD09D63E288405B78A646F44C87E +EE22C8596B13188085479F75F63D3D97A28F9C8306FD207DBFD38DEDF0FFEB7DD80B2A3292DFBF1E +D605ADF1B33E85B010309E3EC058FCD922B1325FEE71EFF2DBBC2E68DB52D513E024C01D47CF657B +B61C9734649A4AB63C0AF4720EC3EFCD82DD3CA6E80BB63BCF1B8DE810A0C6C517C63B76FE68C0B2 +86867BE102424FC31C4937048B6F323D039618586FC21731005D949E7D802A430DF8D2F0CE99F2A2 +376C2953EFC4184355E4D12F422C9E1E25C4DF38DEA334DBC89B540E14C61A7769D77115CE8968FB +76B27D0863CEA2496783114C24D4CC816DA884D953DA3F9B9D3AF8938BC607BF26A071956CA07E6A +5509EA2F5D80E5CBEB98041B197FAC760976EE75B470DC20AA023BA3F63C2876EB281FF5173BB490 +D6815604517AA1B1FA0631401B3C1A04CA103E2CA4ECCD83874D9CFC8ABC134CC0F9141D9AFA5684 +8BF222342016C556C14B3482482DCE5D0B6EF1AB522AA1812BDD8DD3397E05327EC12748FC480842 +9B97202E24E1DE0C7C0D272C046BA73B37D30930C5DE5A47D96955CB0F5DED8F3AD929A8B42D2839 +0458F5910A0F93610F79EDDB27078943DFE17C716D65F96589769349F3B66AB7B8C004CCC59EF688 +1F745EC7129865A76F9C2D029D4660CCFB4D5F9D412BA3372A27CB175E9D65F759575CF14A5899A8 +D31FF039AC02DBD8391C3397428AC0D5717C005200790785354813C8859BE90E0E17914F6CB9C674 +F1E9A9648657B54E5E1F52756C4F982DF74E73F6E4D40718C71D1D0E2420FB7462FEC9E457C0414A +96E475C6BE2C10437096FCA0C942E995A9ADA789AB637B648781D32DFB68E62E91C2CE7E13680F8D +31ECF8C824885FA7618981CD05FB335AA111B409C59EE337DF4E5F9DCC920A5FC0D620DC07F20DAD +63F4FF5E0EE5A2F390AF1C32122BA7780F210229E5A5E3ED97BC1C3CDDDD456E739CA782EDBF4B81 +0552368E9C734B0C78B0B8E3F8B2DD782862B74318871BB1EF087828CC173D7B049811FCF598B8EF +DE4D9BC5447F4848C98029C854F3AE461B9D46DDAD8CE67A521F3C811A81A396CB0F80F3C8D8EC88 +30532FB7F9624F7CAE0F8C6DF875073333DEB28AAA90AAF486AB8C932553CE697B885E71EC8E40C7 +835CD5D59A2C695DB9E51216FF9B77A15B0DA63717FF25B05B939E45CF7FBE490E51E9344213B32E +115C2DE14D76DFD5845088DE645B0E75042A61D82FB1753C445AD0A956A1263E5A096B681D3BC51A +9FF32EBAFFF7ECA8B59D40F0937EEFF38312AE57462C7BF3B1FE24D2BA8DFE84515270E09063CE3C +80DF4935E409F62EB4F54AF16A186D4329972B9BDF15FB08461B688ED49928429226CAD9F67C9D63 +6D1375CBB7B08A5631956B7FE29CC9EFA8D75C9E4919C8C2C54F401D2E0D7BFBA40C50CAE214D210 +C6F3EA5802339F63FC4C1C1995787617F3EC2C806CE44CF8E29F76606CD5836F6E5A2E423CD791BE +CD3F112F25657DFED9366FC4ADF90B685CCE4A5698E5FE16D7542B913FBC01B288DD13F43DB2B1ED +8CCB80159DBDC90A8132125DF8DF547C4851CA609D1F6F4D647741260E845B457937787827A89E37 +CDA06BB191669AC84B8608EAE132D10177F3FC384980F3A6E439B048A38D0D6B9CEF09F3F2D732AA +71BD058169D6D0F8C9D146D9DA046774027559A8B3843F6116B418427E78476AD8F0F81E8A6B1209 +8060FF7DD686503F972D6C42FD6CC29C083AC3D72E3751F21D2E44A572EEC80E81EE44C90FAA7AFA +BCD3ECEB98FD4068F6C3A4DED0E6CEC523C9A0054D1FC2A8D61A4A26F9BC250B8F302416924AB22E +722297888B85B9C12F8DFD2A744CBD143F9B2514C1CBE988D9CB4E77D90B2EFD5C2A528355A35F7C +4AF039C7D1D756305967B847D4ACBB81263D4992C001E2A262B9FEE2D1F5022BE5B15E1D8F1D67BC +52227344EE912C018CB73E5F47CED54FD202627777BB77AACF3EE6B22706FB2FA9062BEE87E22CD2 +802E7706322648DAA0C624EA885430175F746E1F536F9A8E1C610C4A761D07248426DB63C9319A88 +A3FA449C3FB8AC94C6003C745E6BAD717A3B2EA3862D1E08512A98E57772A62F85F1E2FFBA40E2EE +43AEC11203DA9CE5AFBF673436F2DB6AF85BBE89D802F7A9E5FA25A408DB69E51F0577DD26F94CF2 +BA2FC53EDDD6FBEB534AF15F74F66EF8D14E7FF77D8A5D284C8202DD5A6053CEAA606BF925992382 +5EF4EFFAA8D878652A4CAF2EE43ED26BF3590402686C876F86C1AE95046E527617CDD3C429BD4CC3 +F9654D2C76DD4102471FF746FA9FA379B16DF96BFE3836D43FCC0B8E95120C27370049ACA4AC313E +1D50D72D1814F2566B8B29FA9C9C20D0488743722A766436776783B939171FFFA00E04805A8B5821 +4D4F114F7B9C3C17CE7486AEA2BCC895ECDE809502BDE57981318A93F23016F056A421B733C4590E +34AB08BB348DA4A48F19B6BEFAA1DDD2A49A6C440443028333CDD48C85CD698ADAF3FD8676739E44 +400A98B575BE02350576F96CFA54D4184BA47555B8D12374B86D038D085F7FA51FF4BE2FF5981408 +999B48B2FAF305212ED54B2E371F5A0074CF68D1B0E5CD279BBC8BBAEF694A89A6C43F518D01BB4E +8402AADF34E96E9B3FCCAB4CBEA2741D3FD9ADF7AF32388F7771845AF99965A6078F4DA335EFA436 +BE36903E33A743C112C0267309F266DD44FA998C9A139704E400B89DAB952EECFE2AC09C82D9F497 +5371CCC27DA37890EC84123193314D8A7A707C217FFC951A547EE5B6D1B7C8ED85BEBD9D3F4B9B09 +6A78E5F7DF88C931E3F396973974454E59340CA51DBFEA1A00DE084B64630E26C6D6A3593B828814 +E27DB0186BF2A87EEF268AA1B135AC09B52CFE53051CBCC88CEC5657BD47F603C8E1A6249161684F +D9084AC279F57A4F9BBD0A546A87E147B62AC860911969A29B8AA20E3AAAD0079D64E6BF1B0F2CE8 +F0C54C9019207E1B403358253C2FA93A662F63B9380B65C5173C198D86A3D0DC1800D1F5378DA39C +E8523EB62C6AFAD8A0D7AD1629F2CECAD82B8FDE38975303768C7D3A08B91478EDB3C45A8C6B7725 +EA8596A8ED50B8355FB852FB8966479D12E1086223B1E6523A65FBA81DD106FE254F7309718768AB +009FF7714A8C363B09DDA73CD3F81BF9C0CD3B0C806CF3B7BBFAB73E46FACAD2480EEBA97AE68EC9 +4D3D79AA01ECC22067858EFFA9D7B7F997ABD2CE5AAA8781E5499E8580C405681CC63EEA53BB47E5 +5ECC5BA2A7A3C5472DF034B022F455C60FFF971B01583A29E211A87F7163187B190B0C1083D696B5 +86E9438FD8BAA45101A5EDCD1BE5AB9A585511089DDAC8DF1B1FDBE582ABD945E67F99ADC4452988 +A9859E39C90EF794C5C4E62997085B7A16A0D90107D08610BA175AD66377345662DA7DA4D8FEF847 +EE5D57E3AC54B928A0957CC1C944E7FF14658FE4A641CD26C61105C0F136A75950764B69CA17509E +3C19351D456B22C87C55E8DCC4ACD3E150D936333FF36499AD6B02B6403DE0F12901301ECB2EBA10 +324BA72B58206A13B8F37B0AEB12115D0C12879C8EA8A2EB70E85C95434564BA3DFF481C8972587E +FF74EEBBBAB14FB32B8A84B8FC42EBECA65D25E8C32C19CA5962832BF45DFDA4E871508AEC318495 +0D6DBE89019CEA29E40484C36E33D76B756255531ADD1DB24C03B2A64A47BD8FBA3FDCB1F5B96F8E +ECB60D5834AB001A70740498720AFB6EC03445CC35B51F7987109618C6C78CBE3041BEDC69B6FB12 +8142CEC5C8683B558AFE3024EFF7A12D04EF59A72E156DF11D33ABA08A8EEB16259DD9529CD003AD +4EF4137B6FF1654236473DFB93F597331A5E26C7796F528F65C94FE07B3B4F4DD49034FA0CC189DF +CDFF70C2F1C6D3DF30AE103E2AC5CFF20664AB934CE5C19693292071C93BD590383E0A1931E04D1D +DD18071DAFB628F5D7472E457BF81D6064EDFA8DEBFF91701C5038CB30865D6122076A336732DBCD +B0A625548773D0013648A76F07BBDC9C16284D158EC7A105AE37A62279419C3A2F360D0C7A74D6FD +D0E36DCA2A8BD59945A4196598F690878F84C894852C1811AFEA4BE3B9F6A5219E6628C66669DBD8 +FA9A0CFC2DDE7716A356FC4FB271D8A2CDDC8D4684DE447355BC7A287DC56852A638C5777826EB6E +B72FACCC86F80BEDDD0D649A883CFEEF4D74750172A90B5DD8252592FCFE19FFAAD868E99562DAEA +E70514F5DE296EF7B57E6F193737ABB6AA317956584423817E11664A67389197AD9F8F771EA59551 +98C9EE40A0761639E638CE9D890DF468642670235F1373D3AC6B1F43B5777FC0A91A96E095E89BB9 +FD62614DE456CE7AFD6B855112367573FD9FCBBD4A4F9C676E672D62DDD34A9BFE8311B6175A003C +D143C0DF15E4C0B48C735404086E48AEED6B6FA21FD9F40B84215DFF287F0677904E2DDFDA774A40 +19DF45CC877F553E95A1C65DF1D67BC0C60E0BBA4D205C0DA3DA80229FDD71859F65AD04506B308C +2B783839F31CFE4425263224F08C5C7E98A2C9D3DC8EA5AC1920F4E395413262E0836BC019A092A0 +DECA104EB2DF6B63392AE8E2136379140DE5FC98B0B69860FE8E31DAB5C5DF7807D19BEA34AC14E0 +ABC6F6519C51247B104DE7D912C5BF6EF11B48FC6DF84512E9F5FEBB48F72FF1B722BDC3BB2E835B +2E7CC6324BEE84893996B8DC2D4DC2793A4F69C18E63DAF04A7BB5C0A9076E2D5A343E134CC3C89C +4712900656FFC202E1988526D80C7FD9281FE47FBA8AB5D025E63A84051F6B13167BEC15B346212C +BD051AFE7A98BE3A2491F3C469718A58E783ED91F90E274FB4978F8719E92A99A1E8F142EA7E1F2C +46AFF0A2FB50F4D105130CE8EA309B0E480DC8F80D506172B609EA4BB4E2BBAE98D8882814FB273E +690DA990B60A9CDA20A2418246BD10AE67D846A0FA815AC25858145ADDA106A6778A11877FE59A2A +BE300D7DB9BBAB31CB5B960B7E4EF91D4600886D8795DC361CBDDDDE05EBD54B1941F426F7FA8399 +270D2F54C998BE92D146227270A8E89AF90C48BAFC4ECCCA01E6322AFC165743475E752F39BDAEC4 +9297290510FFA264342A0AFE2985F85DEEC66C36EB4A1D46683EE7C591A89B81569A8566AFBCA268 +10DDB0970577A76EC8A066622606B08315DB0F2E6C671F3259C73637D773D1A180AAD66ADADA2A65 +95B5F481E5F59E51CBA876FA06D21E1D674CFAB46A02D267E20234324D0891E7847C13C69BFCEEA3 +AC55F2EAF753726BCEB0DE1EECF42ADA964BF9E475953302C2FCA804B70B779482DC9319B40381E0 +9C0096460AE113C19A2DC9157FA138CF0E7758F71008E71D0F7599744D647B09B16E3C795C56EE5B +D14D8D63E7A512900D67487975EC9CEAEF69572FC3C2342AC5D365E8A4BCF462006B5268ECC15754 +94CAD9A9E7A9E8D9AFFE49AF647C017743EC7CFD5E66F4E4D845A6BBC836849274FBD270CBF263F1 +67DF7E26BA91F21C60F96257C07523AC37A2193010E976965CBD75751E312817C0564E1C5AE0CBA8 +BD12B01122D07020A0852120680985A8AC987BC33BE863EEC52AF13435B6E4048D951F5BCE36526E +07A8661CF2538F69D1F223BC53BF5896437D1BD46F57D9698F642F0E99C7392D8EE47134E34DCE94 +D392949B418D9821E12CAFA8337323E8469DAC24DADC6AAD4A0DADD7FF65694BA3A27964D28D8EB4 +1179458F91CD3F83B8F119BF5E76184DD29CC4C0718CF7945DCECC993A7A78739363136CEC7F2FB4 +95EEA8CEDB3EBF14373A058758C442939D36774435554851E9519B6F09C31EF26B6CD997DAFA11DA +91FA9759F17B7079164C5B47B99CCB7A876FBAB1D0D5D1E1A2683CD6914E6B3B755939CEF1C9168D +30B2738C4349650CF86C90D2542FC9B90F36A494C035A1C86DD716014AA16E6B9EC7AA03B16554BE +C436511DD3097FAB1FD0CD49EDAB96F74E8FD26400FC748CBD9EE1EEAEE24DA30DB6F8734B52818B +3A5E510AA5C14E42060898033E7E36CBA9A64042CF94A74E4B52E37AC027C0DC69BAC4944CCE12E7 +AD81AEDCE642EC34CA23E3FF07B8CD35DFF19F33C8D4DBB56A52534F8A827BE47AD4AEDCAD83B273 +38409FD1101C4DFF3F12D3DF79AD1FCE65B2F419451DD059C88BF066413E23DE27D3621DAC2DCC8F +9F3620DAD0F4B1A6E8C9E6E8ADB552E1EB2C4B2A3B73986AD53ED9ED8911F82F750DF05CD2EBA3E1 +B0DF208A87FB5ED44C3296B803881C1D9776D13350CD29C3F716F0B5A8B8557812024BA70069BE65 +89AA579EADB1F657712DF2570843D7C5FF7F4009D4D232D3547DC8B92ED5C4DB77B76255E661FF8B +163C6F3856DE5651B597EC7C78B84F0C6C1D6EA3A82286F1D3BB45F708D564E139E81F473C705AB2 +56346328DAA64D1EA8645DC10FD449092E0634D9D7344B2AEC3C75F6B6CD8B3F3867FF3CBB0F556B +186EE9A7C26BD2D17C8A773055D9D5013BD2F937D697A770C57BDB36D922CB911CD14E7FA14160BE +19C1A052E297B1A2D682D4BBC9F1D2493BCD7CAD2FA75D904C5F5479179DAF7DC6A4E0D269BACA2C +4F2430B4C8CF1572FBDC750A05DCD5B09FA3A9CD6F2F2A386E2B3D4D8E257BD43A783B38E63BCEE5 +03EA96FF2C373181744A607F0CB8D281D7DB1A6F4076AA3E2C61914BD796EF8A0873F79F964FDE28 +B792BA99A20C3F1F5ED1FD189FB1867C84DCD6AF43D49420C8B1F3DCE7DBAE71DEB17FE45644DB24 +4F44B1011C7C768EBB7254F4DACA64E9BA87AA7CD0F0C4B2228FFB9EBDCF3DDE4DCED39399FFEB34 +8811547D025320A88B480943A339E2CD2FA3605AAAE87939B1D7901465A1879BCB4C5BE1A179E7E3 +71F1BA2E0844F88AFBAE9B78DCCA47AE8AEDF5BD3D458C7D4A7A08ACCBF880D1F1DC69C636628DF1 +EBDC5C42FF88FF8B66351F3F72D703E52F3CE91E4E00759753A599FDD863788E99858498B66B93E5 +083BC3501C39A9BA928B0D763C28826FD237E949EF0BA85CCA9AA20C405DB6D5612DB718F7B4AD31 +D253AE306E4D7CB615C59AE668D347A4E60FFF7B103F8BD0E7CBDB142A763BE88AB40EEF6B8FC200 +458D728930AD0F94FE52ACBF0657C4907CC7942710AB1FD8BD149A9C9DEF6B8DCA7DB9062AA7B1B0 +11ABB5AAE8B77893A023F9EEEED4A20FBC30F922282A7AE2F1ACFF64151013D6B8AC2EAAE58171A1 +0F80BC18C3BBB5DE1E22EBE6033BF83040629023D74CCBAB3F1923CFA4A6735E1DFA8A1B261FBF1C +397E26F3BA9C2629CFDA84DFA3D1087EBB19DDA7E2D76E30DC2E15B8821D5291DA1DFD73940E5560 +A8A6DC91BE0075E3ED8D9E8CAC85AC20768D868CD2DC45DEADCC8B59AABE6EE5B2F891E0D7CBAE82 +0F83479332BF9707486698FE196C72EF72B52F54314329FC498171782BF160E1110A19B8208FC591 +EF0F0DA71AF657B43A7CC649A8488B759F7B69134B4F9DCF79DAEBC1CE52CC8015F324C9D46320F4 +4E1551EDA6D86139DFD1DB814CF38A22A89FABB4F75FB896B00E769820F763486E86668253CC466C +1529A5A924CC337C48448851A381DCEF63A0A302B65203D6571A1DD1FB9DC0C3BD6AEF4891497033 +109CEB5A481BFE442249940EC54096F1D0F2436D9E60495D0ACFF967A741B30467D24AC6B0032213 +18666B951EFD45324987B10BEF4AAA0FF1DF6887377A7F70F555DFB9FF1001C67438A167A00B05D2 +C37065655173A7ED9AE342DFA1497FB1F2FED6098901249A085D31B66DBB6AC25EF16C106B0A6FF3 +47CDF66434DC3F0012DAADE80B942D522CD59AF4C31C1C062157B3D000B9CB86E2AA7B4A5BF31605 +8A0D5A148EAA2C67977FAA0966E4C3454E08DF14C2498AD76E389AF65D2C139A6D8675298C46ACEB +7DBE6904C373C06E5F71399B2EDA0B40AB96E8BE991DDC39F92F1D24797F9EC9F2FAE25669B43754 +E2498E8EA5C44B176C3FB3E8F7A7A1481275A461F2549AFC4CC73E28417BD8C5212C13105EAB967D +AA679AE822B9B75B372A99C7E82D6BD83AA2BA00314DA4AC51B9CAA30D80507505BE24BAD0A87C5D +5D7336EDF60CCA4CEC8201D243C3932F74D171E2409D789AAD0D04A7BB22FB6DC3AB92AE33FFEA89 +7C484D741039F38C317EA396A0FBB9F15A27D87FCBE007558799BAB73212B6E5FAF2080BA074724E +AC87D88166DBC1464CF5D41B99428851FF1D99246944511CF42C3F9248513E9E51593F253D89C604 +388AD7132D6A169E9DD888E020AC1F8BA606F2E1EBB97977E505D8C40853653D8F398F71CC9F8F9C +540C22A1E6195BA578AE7262FC845FCCF77B33F33EEF266489AF8B81A615D6A13464BCA58BEC16C2 +3F31D678F14A938BEC31272DAC3CCB1B2DAE577A26BED852FC59843176A5FCFCFA0AB7FB00D2309D +E55C82CB9049F44FA61F1E313205A76317C4CF529A4456019D970624129681F46A9CD7950B8B5C40 +61853040113C8115319E68B37F88D864C6957DF813B305D09E6A1716B10F26F2EF5C727FC77AABBA +73E12B5AE6416AB19F6563CE14046B715BD4CB2B1E4D315F42D10F74CDEDE82BCDD524A1A5460921 +9084CF1CDABFE72CC8375478B41614BC18A914903596D6FC2F361EE519F875385F4ECB50F7053127 +4EBDEB14A5DBD906A60817246042E3799BB3AC647CDA7244B7998AE4F3BFBE5C767FD2142E48518A +4217599E0EC2CF5E86C8C270FF8B02F949EE001D6A439BCB4BC7D7F7C8167C3AE0A7E59687FB8BF6 +F37BEAA164541B8EAFD92E9D152E3FD0F413C99CCC34FCD8AA455A0B55DEC846A5874B94FC95CFF1 +BB386B2A1E22CD1C3914264B6D5BD1746972857C9235052D77A6C0DD3019F8A307FBEE63A3EF12B0 +39B224108276FFA84021F1AC5B745C54690B3FF587B4B1710AC3533A67BCEFC503ADF1F4B62B2910 +B31965E364EEC9CC437CC40181A7320CD52BE9C546B8F1DC824312216C2FD8232E2BB8D40EE2E314 +54C09772A387F9520E331456C269F51A078E6ABD9FB6A68BFD5F557215B0BBD2227B8959CBD1BD4A +EEAB094DD18E891C61FB00933C0A0D76174D169C0B6445D34C00DC9E06D85EB086C18F3BE27DF734 +EBB9CF078AFF6514438549CBE92A0C0D25EFE4A527D86F158B4E9D8870C7AC5D6C059643A3298079 +CC20398324CA87273B86ED801057D797D91BC3CF2F96C650EE1566CD3CF8656CC577D38B830201BE +718DC9A494268177A5019546EEEDBF101996BE593631654B638C75A6BAA648CD1E7AA9AC1EA60F4C +D604071C89DCCFF8B3E430A57ED6DE11C5837E78956ED991058F3646219BEAE94E4D9381A33D48CA +9B8FF12B54A73FF869D0EEED7E098D80152295E6016CDD809173C57D1F5FCE908A37010AD4C4471A +53451DE9B4363B63437C374C598F548F145D3D288F42531FCF36A9CDF72521F1C0868FCEEEB1857E +A983F6B75CE245D875BEAD1BCB8819E5464518E04717B78BD6E335F0AD77B832AF5682062A1E2AC7 +7CD5EDD5DC372EE456C96D38BF8BF348DAC2B4EBBB2440F2CE97B4B337F2E23247E3E8423BFA9237 +CA6CEB6FB93F960CAD894A96F0371168A33222052DE9B3BE04B022AB95C0C243486E35197721FC55 +311DC55F87BC72D09B6C940CA36E6640AEB66C394A5949A604E7F15DCE3A008BB41B0EEF2840A357 +F348443B4DCE064B4C15E5EC52E448C985FAA1C3D6526270B1CC691009959A7620C9A6202619A19B +E410FF7BD535A8B2640AAA459DFDCB8F2BB35112626497E8A397D4F9E04788322A738DC8907CB643 +15CF63C95809E90D06EF02F72AB04AA61FE02ECCF7E9049FF9F3EF2258A75656178AAAC9F3C2A26C +001341862D526CC14E92A81BD63502F959066E0BCD659CB9B5A45606153DD77039B8C5D5B13565F0 +0D95A41937CF97089F3938E39659A64DC3D6046D0E9EF66544CAF8A206635DF49926A3EEF3FDBC9D +CCEA2886EC855F1821C4B9CE1D02A19A11BBBEF43A7D4D536715548A62802F64AF30BBCBEA8C7E55 +AD56C801D8A569C8183615A78CD393CA42C103F155941E845712C335F4ACFC7807202B92A983111A +ED241BBB8501F15560E8F2157C29752BDCDB274008137277920053D6D7DCDC626A574A82A8A34F1E +77B2FC8CF7C1A7322F22DFCB450259EB450C52B70DF3584A7C54C813DB41E3DD81253A03B02BC252 +346AF0160716355797B6F8210C453DD7E1E756FF08C7E6A5F4F87605E1DFF35A130D79148A57B7AD +12D94A129FE3F055CF974EBA09A2B13DEECA2E02EA818A58B81E8743004646C7746110BC61B86ADF +2D5D8C45A6A5461EB34497FCCD09E711F47BFA742C73F87B257B53F30CB68D151424DC3C210D3E8A +C67C2495A8236EA2D7985A5E1DEAC699D7B700E6D38EEE2E93B191BAA5A8A2C916D206C63FE63427 +AAAFED2B5784276FC21EEFF2D70E47C8540DCCC3E00134642B703795CD3702631AE2A90E063A218B +61E5B89BBCFFF84F567E37A31A9B349717A8CDB9C9377215BA838FF7469BC486B64EF2B6D92519C0 +BF0826E3652903F40E400689F5749DF86FE3DE178E21E20EDF9053081F6510D8F19ACD021CBA481C +484D30EAD3B84ED0190087EE478A17154B243346C3938FDD5340CF6E47B185E64ABDF44F8CBCDB82 +94492B91929BFEB9DA2B033C3ACEE554F0F1A7F8A56DF7C06A3583C1E9C5CA458D40E550FDF3E2F2 +E7BE8312D5FEE98543388EDC8A04CA29F1B82B7AB4ADABBA3F2C331EFF3521B2B92F99C4377AB827 +A989B423750D36ADDD2E286E7F3B694E29B8BC403693C6F7CAB5FE34F1E48C8D41B47831E8C3F5BE +5ED5142E3C44ACF5180CD41FDA149B1F4AED36812E42BC184227F5034220F74F67830255E1CAEC12 +66DEFA358A87D2E3B4B4E7EF30181570D0B2B43072EE0311C2C157D32EE2BEA8EA4251B59F6B61D2 +B4FDEB654DEB67AA3DFF4AD65B727F0D6B7D61523E4B44D99BA5CD33540F340A35DDD466ABEA4E72 +E504FC9BAAE51D231C33A8CE7DC2970DE4C1FB5B096A3D9C641EF77DC9039886831DDD01C4F21E6E +168E38BBDDA5F4308C959C7BBF36A42D042DA6862937EB20D4FA2E5927741A58DA5CBFFD9553BEFF +BD92E6D64871D8B25D9049F4E71970A8FF5557D1DE83DD24286D6C3E4770EE00F9A1A0B0063C9999 +4AEC75E84D6F9C488434D1F3DCFD0A8BEE9ED8257CA97E75E8B1285747184D6D2228EF95D4A0B8DA +252318ABD35C8398FC6568B294D90AB308A7675F9F160140F0A08C88AD0CA1CA2CF85E4D031CFA3B +87635F1398EB7DBC666A259F02DB6741D13E11B230025DD6DD64C438409AF109090058151E4DFB8C +0E9CD65935C4CC063CC6100FDE70896E23E3661C7FC1B8228B26A55903E997F80207EDD8863FA074 +EE4FF23BE585BAF708040C9F8CFDEB42FB8EB71D4CB6D7757E973E4D8C9DDD082712C23F868E1135 +ECD91250BB4335958B07C12FDA75EEB56BE19D1644C1F76A8811C021122619F751CBBFEB1D3DC912 +999017FA163672A1EF754C5CB78962BAAB76EC48461B492FA88F9897170DE857CC8374C8BAE417D4 +C78A56047024731F4A45145F0393A27CAB614A7FF747BBC28E6880D4D01C0A6CF317A1DE5BB5ADFA +4B5FBFE0C57598C79F25AE57BB797A489D51F85A9B9CF8BEA64293F8FCC43B0D5484DF99DBE19152 +692CE756F6FBE8CE5831CF4B8A5AF47524E272C45C62ACBFBDFE7E60B05BB1A1A6AF0E9210012014 +69B3DBB49EC7B23A363FA68417B7118DCEA71D4ACA2E36F88C6DDEFB70205DF3AB7C74CF65CFD01F +F85FAF99F172689737331D4C6CFF7A29029772F487FBF625F17BDAD89B4AC076948277B4ED687840 +301016C2B7AD4C6D02F81E88C75B7A04D724E234E38A38269351582245E361A42C75B8256AFD5624 +B558ADA2190F960A896BBAE7A8C57E76DA10DC29E69BBF3AA86214C001A27B39C1D17C548DA5601E +86A5CF53E7B1896BF003AAE9387ABA9B102EB1E9002DD3754A378F3E49F2C6EECF47EB1BAC2CFCE1 +1AC0C5CB063672D32733563F3E1E891B6073739BC53AAA0043FC45E90E413DFBD4548DD320B681ED +70A7443A233D79E3F038D26975586E5CDD2115AA614727B1F6DD4024B85CCCFC79D10B7B6AFA789D +B37BD0E8C423C1A4A8681B5FF3A9FA1F61A46E46C4B1836D1AA41A89264A7F4B1C259E4B10ECDF37 +5BD26A1F412FE01FBDC03368FCAF48AA0EC28B1BD603A6A0D0DADE66D14C9B7285569230FAB76803 +35BE104305E4B748FA99FA31F23991608DFDD2097DA292551136F255051C9F7EEF3FB7C7FDB4E651 +C3D03A4CA357B587245236F4FF3252563F6BE08EF8A3EC09BE2BF27B9120F7D37801F6999EFB1C8A +D1A08698CC59CEAE2CFCDBF6BD8F94DEC94F7EBF33AF05F52C85760C63950B455510C6AB9398D09A +C288EFA09E8F631A59B03FBBC75BBDAFD675FFACCCF8ADF71E815A4A49F14BF70E42DB0B7347B528 +4E234C24010E2177DBBD57648E398FA6B54571A37BA8C989503594D03C6E60871A7F964599022154 +02BA168B8D1D2685F5CF8645D5E11A1769473027F42564C2966C10C0DEE1EE1B6975852A4870D492 +83A470E623337544A7CDA5C16FE2855BA2A548511FB4D4FF2E3E78D108E4C734F64EE2F12CC9562C +BDF363EFAF5201B673AD00583FF108AFF6B68055A5F299452D176EAAFB92C84F114C8C22A05EAD65 +64A3371420EA9E646308DE97D40705E1638DF08704FC90249CBC0D2D3E884A4562CC27370B1A9738 +9D8EFD237E644A7370B8B38ED1C377F522C75F981D878A5E87101E621DF9D85C7207BBE5A87CCB60 +7F93A2E52F660E05C83A7A6CE6D01AB4B62A1EF8DA47CF97D4BBA0FA8EFFA9C0F61A325A97ADA694 +45F23AB1FE27A66C271639F839203040D44B11ECC6E805FBE88843B34C4FD52D1D3C6C70FFED433F +C04501FC20536ABDFFA429B8DC8192B2D45DD9D646049CBF40719C3D674773F9676F9FCF32817DCB +55402A72C56D74AA4CE4035687C730B6B44A9CC614BCA5A3FD17C170ED949E588EE45E89E18B0766 +2A6327FB9E8475C43E5DA1B0AF07C23774B19C9EF59281F5D884990D6194170D8293A86DB52A0FE1 +7E88DA82209A00A16BD29B8B2F13FD60AA25FCFA9745F57C8216283C1D6EA1C119CB9B8D57C00419 +5210FFBD56395A3EC2D3098ED38F389EFC0324FD0E55EA339B3892568229D8D3E205A821E8219FCB +1A7713FCF3450F8BEF976CA0BECA47376A8CA73DF85B340C67EFE4534D459617996526B5E5D3D19E +17CC5449E5EF2B82B2C4C2131FF8A19FCFE6A186A9840D872D85C40665A7A04E67EE26B8BC9206C3 +5B44C8F8A1AFC3867D96DC6D48BD45063BE25B882E9BC0D0948C18DC870E6925818E1FE17D336217 +F174EB4481F5C0ED37A3BEAFAF4D46F857811B6728BEC461AE6468D87A736572F4FF95B58B04564A +9D3C22754587DF15495A319D822B838461764B73483C1F7CB930EECC6F7424841EE10E4087E95120 +2FE88A391375C96BEC4480328A54740213F741105B12A39F19808F3823507B88115D468C61B212A8 +ABAE7480E39BA52390A1892C7EC50271156B4E8076FC3ADA222695DF372385DA7B117A29E04CD2B8 +0A320F186D61C963FBDAFE9224E537057C49E82E405196AAB621B5FE4011E1782A747EF935ED8BB1 +1BDA39A141CC0BA42D04AE123383BC95A1D03A85A9440010C3B9613064FFECA76197E10919BA5006 +F35837ED9BCD7DE5E6D968AACB6FC91178091FA467EF6FDEB728E17293DC89DDE5A5261FAA95A2B0 +000FC750E7073900D4D88247DA464613ADC2B3903A6132D96AC0E1C564385FFBF6249DEA76BEA2A9 +9160632DD2FC2B99133E9F2F470F72B45D6F18B45020F604B06CD9174BA3805DB60EB9C5E6A9C789 +ACE76AE9C79C1BD34434E95E501BC968633AF93FF4883C6A596776254C0C74993710327086B2886B +02FD3E42A725A03459CB36EE34A094139AF5FCF487D3DFE63FAD20BF0DFB60DEEDA2ACCA3510E963 +189D1256EABD81253F7FF9D11263FDBC1DCFDA3D1EA2E52005CE3C605C993231258A717423F64BFE +EBC34684EFA676358B9B543C2042BEF954829FE3246A879845B30EBACB43D8DD7A20FCFEDF763AD2 +C5D20A798B69E08722DCE6A5762E249ACE3055B650D9E110599EA30DE5C4FE7200D5A8DA9E1FE268 +6350D0DF334877D0B9F6524C552D0B6DFFAE125EC4C18F7547BD51C14288E4ABB7F8A1A00458596C +390AEEE6FA308AC1F788FAE30D7F8928AFC91D4DE6352D20B19D8D8AB122B7378CB379C5BE7E3CE2 +922FE667EA057B5D7B3F0B51C7BF0C85F87AC2F360D82C38964F4DABCC9104B32F0FB8802235E8E8 +D9A5997D392259074C00AF2CE1D2BF7B8E90E2E2AC34185C68A03BAB8B267778292B227245D7FF86 +70786E3F746F86B9D4D17190DB859A0E144B2A61E6AC9254DE5DBAEF20E2E9DB0B2FF654B996E962 +F55E465DD238BD1643CE59DC2B5A58B1E6E4AE2DDC2D74D79AFF3C34E4E593E051FDA236B79CC0DB +268D2A89B1878051223BB8F33FF99BA87A4811C0B3BCC01171D0A731EB732ECD8749D27952C27886 +B252F9C3D190419FD2900987A0A255B9753FB7AA70C37462134C467A2C4B7920BED9F9E86F8F98B9 +6D00AF8B05A4BD5F14C2A0D914A9A84160D554FD0718F50ECB5DF5E76623065852DAA74C9AD6DA07 +A119DF12C3577FE276AE551D48B1C5CD8A50E84DEC9CB0840520D78FA7F9A7C2071E28CD20EC7649 +B991F3818CDE295CDB6085F24FCF93147E9F4DD084FBD32525326D2EA147ECD5B6C9D9F4A7166663 +AD18BF234E9CB92FF72138A8A49E73E527E9A6488A4CA808AECABC94D693CD2C0C357D285F65006F +A2F9197F61FBCA6EF07B013E2B558AB531D2FD270CEE7FA8E467FAB885E90C5884843AA08E2BBFEA +0AA575643727BA18ACC499FF34E3438645BE2AA71EA491E54687CD305E12BBC94FAEC848311AE816 +495B013BC5075A2D2AE54A7AD7C9105B64356CB51F18C2C28E3A83B9D81A4554DBEC9BEA9A660CF7 +E1BA89E6D4DFB3EEC6A3DE3FCDED9B2D614156EDAE8CFDAD5FF0EFEE31DA3E6A54D94CE9453A1CAA +D9756D91BE85315F6514BAFBC821EE810BB5D8E1B8F05F64F3F72C4B35D424F7E4DC3AB581B74ADE +B6D6297CDE7AA8278909F269FED79B7DFD39B1C0338E01D556C4DB9CA3A8578ACE3EC3D743ED4B9C +0145E4525E8C315F7A1B98584B975C70F0D415708C8CCC13F848B1D36AC8249B73638F95DE0CD27C +7EFB52BED4339EBDA4812564D7A77416DDF4CC88CFB52D07A252D89353C6826CA1832A153242979B +6CEE783ABDE65C8B40CF4EA7B42B8DBCC0E02423DD693108006F6A4AEBF053B666C3CB63D1861F86 +EAACD43BB9BB6F2C3A17293C189331D253B447757EE7CBF4518BABB73A1D44874D7F0625E6A013C6 +08E991B4AD17A9ADB36740D25E3E35B459B422F7370B134CDFFF3F3BCC4C32B4E9EBF6A2478013F6 +6933A1FA9403A2F1161EC632F1F04EDF95ED0F33DAD9665D54DD9DB2564E51DA7B65978CAB50D6DC +1568976E83B056EB0E3A6758518B6E17E9EBFE49B72EB148B472BA144BDC2AC95744C9BF1258F0A2 +E47470AB0EFF90E190A41108914AB8C1ED6B11E0681778521870E80C16AF2AFC723CAD8719ADB62D +3939D3BC8CC1D8A4E07E9D734F54ECA33D936D2C39D5C8055739C33E53359BD40E576C11E93B4B4C +122BDBC9B1BBF44243AF4F0BCDBDFADE68C526B5CD74E29CE3F70D62BA83C489034111FE8E4DAEA2 +F01F9D938ABB532DEEAC0E329F42453FF5C15DEC2AEA8C198323C9E8FEA55B3F5DC4751D2E2E16B6 +154E7F2ADD46860E9CA71DC114C99D80E7EA1DAB51E925DE161CEDD678EE6282AFF38E3CD0E65954 +9C970613209955A3F581E1ABE485E56402A3DB0D1E9B8A9DFD05C4B0B7F97FC6D0EED0B69AD6F182 +B1D028ADD2F24463834B13F5C1307F91D363891824E81108E57CFD5211F86400D3E96B107F3B1FE8 +9C4908649D04A46DC3CEE0DE66AF03A7FF9F4DAFECDD6DF4D93784CC899B527784DBE0718050FCE1 +85BDE3F39DEBCDD660B2488D23AB1CFF87B0546D02B48E7B7724C9E87B71BF34B5D6640E0F6ECE47 +B182D41C89461F712849C6CFDB7E3F5EBC1ACDD12D65A422BA362A8FD6CAAC5104CCC5AB5FC04A46 +E4309ACAC83D659DDDA256CCDDD1BFF9AB3622450C4FBC89C82214F00C42FB0311BCB1B722A691ED +839CAF9024FB1671F18E4639C96D84718C663A4341DEC037175C6BBD288BBF5A0478298CA726567A +9B74C32A527339C666A294A17F6821CBF243D13EA4B1603C292953308B566653423E7301A032E5D5 +E2B93F1C1434893633DD19501AD12728B5A1D9D36635B589FA2E151140B543D7C5E469AFAE8E80C4 +FC1D9CB6C3823CC1BB7EE40AECB58CBC1465792226B19E0FE79235115F6A3AFE19F98C5DB63D372D +D7C041CD940F4F79F2474D9CEEA0334FA04A97DC9773064895CF11CF73F11B4684F06E48F4469F6A +1AEB2CBBC52994DFAB3319DCE3A0C8C2EFA9627496F8CC84D3DF3BDC4FFCB61672780F294F453278 +AEB9262E66486856D37B7647141A82E049364ED3D03F925284A3F1FA3DDF4C0B48B3FE22E7DF9ABA +239D33CD300FFA8FD4B96192BD568FB18D325CAA8E1F1FD4B27527417B034841FD49E4A77F217062 +3CC8B22101166D80361EB15FA9020D24F61007B0A8274DF9DFCD8E97C85568E76D34AD5DB1779B02 +F034A69CCF9D4EBAA188EB3017EEF5B22A0A552696A574907F695098BD8A4849D5C8311F129447CD +7A3CF88B8191AEC0AFF30A38A9AB8135608A7829207A7D242F6E1FA7DDA19F5E4C28560D42DB4405 +77CC0C5F5803EEE897103ECA0BD944E320AC26553BEE7852EAA733BD13DF760056B2F5BD1243BEDA +BC3C1EA0531017D74B47E18F801A60074D6DF849FD0532234545E5B5E112D1E7385341D39A89551C +80DC2DEAED5D5DA2A4BE5015D297324E92BE64C68428132E6EC654DD4BDCC6640C68835FF8A05E09 +9604B8CD43D3AF2B2FE10C8AFEDEC5A70AF8509D12F662338CBF166D9452CD36331758AC4F4CBD7E +DD52139AD27DC52569877FE709F297444C4F31899D1945C81B14ABDECBF31DC463A4148F04EC4FB9 +703C158216C0FBE65CCD450043ABFD4E65BF8B28CC148252E9F3E797EA0B57B8721C94CBC2EA602D +F2C57E87938C887A382D2659226463BC7D6A1DA87F4A341A59BEA458177D3F18D1213539DC0E301F +6EFE0111FCF6921368BE17CCBB7428127E0C059C2C5ADB2A3F0197F0CEAB77FF7F3C027A8EC3EE76 +CF5C986EB47CB60561C773B3A2DA47B5A35394E29373DBD5C3FF4C9213A89AED77CC4F3FCFC49EF6 +EC7557C521979A546983C106B3627B5FD2D71CC5F08A32BF49332A89C5DA71AFBFB94C949A91220A +B1F885C981423AF93F73BC1CA4D92D9DBAE3EFE6A76E2DE3D0F74FD3255820636E3F1A6B7C185306 +23C12AF90CDCD2C0A728521E9B639EB6345D1DE8FFFC3B19C72E7A93823DFE3115E9E7BBBEB28CB7 +3DB121AED8920D47D8CC08EA2E472E39A4CAD5881B5C4204F2B732AF9D5189D25ABF413CC78714CB +01B1D8CA5565169A919DC481F6D2E67F1D490AEBC5CC62A8F62C1A323EBB55ED35AA5C8D6F8B970E +93205C2701CF4817BDA994FC16197B469ECC5F5E9DDF0FA05640C2E571849571CBD26402B1EB1E80 +3FCF423345007B9B52B13E3B034E8CB3984B925EBFFE719ED4F39F3D0E3343316A6FDC26BDBEA88C +4366D3B2F851D2B244CC4408251AE2C77348CCE9DD8BB9C89800B572D38C5D1CC34C740BEEBB5DDB +0A8BB251655FB989840D23205D16311A9FCCF7C85F6DFFEA9704492A4E7A8F6C0BDC29745AAC2ABF +AEBA02B0E7AEFEB92BA63AB0DF844EB09D505C3DFC1058CE42CDD8043B76398401E1DB862FF9F76C +05E8BC6260A4443CF494BC1755913D51745BF45ADF2F8C7A9546D7EF4FB11E9D94E4539632C2A396 +06D04480EE459408D7A2A869807A4C01881C1BB21C296A402B5E6E07093D833C3DFF075F4DD426EB +87B1B8DE16C146DE79F52F5943015331EEB852809CBB8E1D6460AC4D176FE96F8D19F6CCB22ABBBA +A27C4497D91312C3CFB5BB913B314E43D2EC6AB6897BA7C34CF2CAA6DB4BD69EB5DFCEE0AA917D69 +50E36A68A4C22A60DCC69379D47544A58D640EB10DFE120FCA843B588CA8B94F7869F97609A6FE03 +AC86EC1F7CEAD2EC8E81977D1B946E459DFCFEFE65A7BFF67E66F5F78A45D8DF65AF0146DF74E024 +FC042328886CC1DD7779F49CDBB750345CF83CD678A6A8897577299DEB38AD665DC4F21CE1892A18 +C256F318107DD3E9245C1AD3BC93CEF7B7BF057E33EC9A3F953251261AA3D1A8347261E70A46F777 +3A84F3D4D1A0DF6DD22A96429349DE0D180310E17955B10FBF53220EF6483D03C650A8D5C16D63DA +F65C21ADCD6C2D0B5D4ADEB2F5526AACF7CF42F9A8BF4832FB2D4F73F3D5FFD984B572232F87BD3E +59133ED3D2FA19F7856AD812515C74F7D851574019C532C25F8E163E595FC9C83E3E820C3CBF690D +A62578A980FC0803EB6DB9B1E90E3256BD4650816ABE5EA86CE65C2EB418D0ADDA5F3EA04E17AA8C +4536CC471AC20236E66ECA3619F161DFEFA485386C30EBB86A7AD930FD0AADF2DA69DCAF26C0F677 +206E2030E3B15B3662C0AD03DBC1636EBFAD1F2F2C37F5FA9856B0198C5B1D80B69C5EFFD94CE071 +5135C649C26B9BA1266B0A5B270CD08A706166C0B320915C87B27DE21DEB5D7E4806F6E700B7A06A +4E29B629CB40761983E9CA8E34E869ABD04DDA190BFE5A6EE8B22D7E511B84EA584A84211F27AF89 +18DC5AF8A1FF2D360B6BE3CA8E66BA4CD2CE6A25E7E89406684DA83FFBCCCCBFD0844FE3BECD7DE6 +7764C59C022DB1168D585FE25073FE00E30218D1DFE115CA1FC606AFCB04F2A082EF91788B6BD096 +84DEA31F20034A91AB9D971366F97B5009FEFBF1EF0AD941654081B1E8F0B2EA495069A1DDF11DC5 +6857D29533DC857958B49D1A0779732819FD22E437084BD9F3C4F2CDA4D12CA14431937AB63A03F9 +C040AF1D801F367ABDCA7302E18A9050D6026FBA5A5A7FAD44E31593173CDF277CD737D1CEF59FE9 +684252BC0DDD00A80E023B88222494C1C8C0884230AB11D1083225AFDCDBC1E24D4AD5FAB396D2E3 +70E44A7571B230660D510A5076D8E35F7DB72C0566DFC119EE1B8AC3C0406950A3C4A4DA36BDE297 +040A27F70753A87E6CD593DC6BE9962261A99AE5949340C5D45C94A9AA3DD636CE8B497BBB812345 +7C824F443A53B3EE595C38983FE3E07DBDC6ACD55CAE8BE1081AFD4857A5F52A3C925143507A3C37 +F1992CF72ED0D4C48D94AE6CADDC3BC87AC3A3EF035E02181F78449E4B063B0835E827644051551C +1603E2EAB5875F28FC77BEBA6923428D5521C698C6B7F133B0F689F105FDBAC30A8ED2F29F0255DD +F8A037B81F04EDF004CBE639C8DB0F94D0C5DB92D34D66C2FED66CF8B895AFC4E659D08388EA44EA +E83CE459E5BE306750A682B627802990037157339BF142BCB9C08FAFDC3C3FB16DC3544F62C6C7E3 +3E20CC4FC7CA21E2C3F6C546CD78DEE348F1A4C8CB548EF20C049678916771D83ACC9B7B22784AD8 +580134471A3C79BC86B5D6D0D305C32E6204274351C94F9DF45D9B2AD5B5087A89F90D6AA033E4B1 +D1BED022F36147C7ABD2B73134DFFD50907258E610C3B20949E141172B1C6A76DB238C375021CBA6 +645CDC26B717428B5A9B4D3F32A4B1E22FEFF3BB93FD889E1DEF8087718D5E3E650FE4A3330DA9C3 +7E9EB499DF5A342D8BA4C0A033C3347CB25A31BE143ECBF91384F2381E323E7FD3A82A3197C18905 +3200AE2C86B9D01AB0B289841EA7E9E9A26966E0DEF54DE0B85D8DF084B8C590081E444BAF1E1F60 +670FA12AB97159318624F2AF1B5EC7DD83C1073A99398D2143A52D10A13C201FB356BC9E90C63BB0 +BC2D4C42AF4A8B9C8C4D58A1B32E0597C63B3F8B3E893BD3BE8C60231838F1BC78E73A6C8CDD5E7F +2907F897FC8EE99BFFDA7338BCEFB5AEF950E5549ADFD207AEB15846B509FC57989883642498A381 +1B8E5CDE69C05924EFAEC232FA4CEF302EE3251366ECAEF57D25CFA3B4A9E6397D996F421C900BEB +CF73B038FE7B16FD0A1172AC2F40D19CE0B02FCEB8BC47DA5344CB933C7FEC950184F78ACB32D3E5 +E290E84BE753B9E7A7BFC4416CCF29D023760C06CDDEF2505806A65E1508990529245059AFD301DB +669D41BD72BF7A80A9DF66B876B3553FDF4DD38D15289AF7A1AFBC53FFFF135A6348DD784AB42A6C +0D6AA330B069607E2DF3CBEFCE79D6F63E274C9E73A33EB85246D5EBB986BFA923DF68B2B8CF82AF +6C33E785F35B25B1D1D614DE85A4F4510ADFE42D75B5FA5408A59ABE53859E28B3D000EB9C6A7D2F +67C91DD14C895BA87B9CB57B851E5193FCC2A443AF85FE28DF6F39537F23A058BCF81DD8C04CB2C2 +5040300F4C55975E856DCB4E21E2B5481BDCC05601942FB25BB8A6B6F93E2C2A33CD478B44655657 +C557EBB080179EE5D98C5CEBE0B25BFDD952FFEB258014D7A5BC4BCA4F1A23BBA73C454B12960451 +CE1752401B0151CB2E01D5C72595095EAE91D8D3BD55A54A2AEA89239FA176FA7CD6F16BB0733EF6 +CE6E77763A23AAC77DA88C8EFA7BBB2991E472FF2075FB25A75ACFA70A04C28764F4AE4C12051B25 +B120CAD2E3044DA35C1F94135DBD69B10DE147321CBBDC814CE99982AC1D76CE3D3330E41AB31F3C +76BF89B95EAB81AF3464C732D5B1411D97DB36C9063537F64756F205B16ED7058E2CB1D6946C00A1 +A0CDA9EBBE924BDA6C7D7B605C514A98133907B793C74CA858E82DA3519188CD974B34DAA74265DB +5BC8550D5F0B1173ACEB87458BCE2AB1F96996C811699A0FE4A9B849D39023725E2B1EE7E426D30A +6C5C75AE6BCEA6DB41E4EB2035F7F924E6B9F0DCD00EB2BB014222E55FE387FBF5B9B7C04F4688D5 +AE3529FDACB38B5EB0AF5C3A874C1AA6B17CDA8D1E22EEE05A3DA88449200D3D0D002DB86F6C51B3 +37C8E19F338E7BFA01E1202612D50E210140947D5F350E84F790286C3F679A5D7E43BCDC337265C2 +631527FD62D598B7CA1F5835C0441881B97F5197901ECDC4F195BC665A846823D2E41417373F8639 +567B228FE7B73D781F07A361AA49C3E9D80FE5B2A32C4C1E575D194E841967B08D10405FA44EEE28 +47DB9372C5CC931E50469532F1BAF577F680BAB4E30B7E1CFFA8574ABB679789F69A8A1BAC07B7C6 +4EF5CE5EB00E97B36FBEACA9BBA4A13B0293D34BDBC77AD1FF88E5744AF009823BC262511C4724DD +585E7E17D90F230F7A5861B0DFC42F0B4E49A04EE0EE4DADB908479DEF8372F334C53D2BA5D855CB +39DC7C9550F9D0F7F77E82D5A59FBBF34BFFE92DC9E6668B68FEEAA4F20053433D6749162BBAC5D0 +D428DCF2D58D49B127FA2E674EDC7D3613B1342F4D0ABD7F4C5B049FBF78E804D5F16505AE7EDCBF +4D6FA08D72890F5D55199034572AB4B0C9A7E7F6F5A403198864ADF113CAFF5BF9D4AB5B16F81D0F +C2188FC80875E10034D12E30C0364F8F72797F1AED525A2712A40D44210B813DF5A29C84E9F6D51B +1D60A5F6F938FAABF878D29E6AB252D95D05FC1ADF5D4CE1C9E585219112112BC6CD5C766411FBD2 +2731794B5DE0A27AC57D3C57926807469C360372BE529098C350EFE2154B87F1205A57A0B04C5206 +CC4FA66B8793BBBE492CC3271FB4F90A28D0066E0D7F63B8DD01549A05AFA5482C29560ABD628568 +75CAC16100087540162473498C14087B29B86B7BFAD693E81765CEC781F3FC80E9C7B410E9B55B88 +114191A1703C638DFBB469ED1DD8254B1407003A319CE74AD419B077F17047A01F0BC0AC8507191B +F72D77D9333C9DA8C9DA733EFB5305F49CB8C7BC451321ADD7D896395D269DCDFDD084EB3AA70338 +6C0697E962929651164135C094D9BB1C9B949D5EEBD3BB17F02C98C813CCBFB23C2C26218A2F4C63 +9A8B9DFF2C29406037F91938A5E1227310728428B56F48108CDEB33BD3191ECA89F947271983DB77 +6B2BC897A30EECF2601EE3B2A6F0E135397622AAC1F2DF523CE6E6BC720E13CB530CEF4AB9C8273B +D3D81563AC8A8E6C44A195112DAF824BC7A72FCDC4E129A480717BEB01085DEE65EE4344D0B41EC0 +BCDF842566B1D9F5353B1F6A063FFA6CDB06EF634C8BD5A7A63F991D178F56EACA653DD67685CE49 +E98C7554745A4AC533217662D23E1D6937135D13BC2208EB8D50560A2BAAC319DFAE478B6BA4CA5E +DA20222F0E9BDB0806320ED1665B54A347DE0C42E9F77842DE4D188E7E824EB2F0D7AD163F05480A +7FA99C5A603BBC5DBC843774CA66E889B945054C0ED0B1A4BB14324EF901B023C208CB95DFCE9284 +89789690CC45BAB97BE449F8E2F5AA9276C0571303E9788C46E7F789555BFCDC3FA9ED8DA8AD9BA4 +8B3AE09404664391E63A989EF1E24BB464043AA099E4F2D796E352EB277106D8D81BAF2F8562EF46 +BCFD1E0047E8018CBD973021DC1C1D821AF03F083F0B088A62EBCF2BF6C5B0FCFA441AAD1625FDB8 +34F943DD47A5A42EB3E9A5B49641F797C288B799A64897F1346070461B6D535E0C4ED099199C387A +3176AEDC7DA7E7D9E118E55565092A36F7C74ABF281720C0147F4E4F37D49436466C61FF12764E30 +43D8A6D027E70537164F0E7942F4ACA42BB2CB136177EF7197E76F49AB403F741C0EF902FEBC471A +D6C627424320A8C3A1F04C310C511B3F91C3937D9ACF459999C18A33F2C852EC38CA806599C728C5 +43714018C65E2C5F430F6270AF52AD71ED38813B60440779455F9529A4A1623CB9F5422B9216F9CD +BA913B9A1CD95DA225E254E8101216085020660509D03A034B5D7E32E3DB5E5962A9A27711D4C3E2 +9CD84057F7D0D7E8000947AFE896F8523253391D2E11FFFE523366B05C532D5629A90741EAB3D4A7 +31D3F6D4F03FF93233DDF88BB1913ABA22EB9AA6311E3144381DAE29BCC8639958EEE59ACCFA06F3 +5DCCC63E0609F542F3EE5DFB1CF718CA3F328455726F8F65E23ACD970E4049225998371B63E35AE9 +8DC54D8329B8DB0901FAA63129EDE21B158776981D4D094013C096E9CD020315D123C03DEBA21E97 +E4B584B4BC0AF25F5DCE53C2DC0F3E61F99BECAB40799478BE7F5AFD7F68E23EF50AD6645C967EE1 +1206B6E791769428ACDC370D64E4F2B3972E0E4F442297199350663D6E772FC6777A9B9DE215273D +082CCE4E8678FE9948DC8D5B0E459CD02F1645AC5620F3571A40B4D5A17DF5CFF48B6C843DDEAB5E +BF58FE13D7DA08E8AA7902119248B3B151DA583101CF80853B0150FE05BDEDBFB50A7FB0F65728C9 +3B9DF48CE8AF1DF1FAC25C1D58E1AD30274A00EB54CF2F16029E1AC0A0919C0655474B9A6936AEE0 +FB74BD185FE7D70BB84786997D34A40326A74356A4AFAEE67B6B26D1C1A7BCFF8697B55C816CCD77 +312C332A55315DC54F9BC0A0F12500E0A76B3936292A3DA2DDF5AA8CBB9B5DC32EDACC4827D684D2 +74E65B8B76FB2C2B19F7D5607523FA953E34BB39032C05B1C1244304606C55660D3CA8607E764EA5 +B03DB7FCAB5CF7788C6E60EC8C449BCAFD90BCABA4132B6CBCCFF16784FB59B36B77CF0A9EA572E4 +CA0A01C725A6CF2E4500CDDF5BACCB9094D48925434F044118CFDC2696AF5FC0CAB3884107ED17B9 +BDE0C0104B1292A1F8C99B06FC4A6360B24480BD59DF0488641899B0F42B1311B582717BA7ECFEE1 +4143654B5371C8B9B2D80685AD38D897AD1E64875C28C7020A84FBB3A3BBEE16617DCB9BC822B7C5 +9C5A18C0CF7E80163ADFB7AA03B7CDE8497C1697D90F2ED90F813095C5B91657FC294EF0E341DB33 +92ED860CB2E0AA09293D0F99AE9EB54C761CA2DB1E51E1CEAEAB276C7BD916C68510D72D9A67468B +09B3C39A7815628FB126CDFD5EFF59CC8184C0D35A5B5960F824BD175495DD3EB12A4E96008CB13B +8C5745303E66CF8608FF27C4709C1D854EB79608E52F068FEC0151A74C125EDEAEA555C198FC0802 +7BBBB802835E1D435077AE4B1CCDBF722354F6C572BEB1376D3E342195FA80AC9722EB2F46E44DE0 +5F5A227B731B8D4A4B6EDEF04AF2C5DEC2EEF8FF48C5B18710ADE3DBFA0C956505B6DA9CCB7CBB83 +4DB6CC754948855D833670FF0AC42A4773FEA8322BECEE04CA74AC2D66855132D11A51524488C547 +71B5B7A512796D7D7AE0F9C1FBC9CBDBA0831074F4D200349D0CA40537B92496692766F020AC43AC +01DB8B2AA2EFA9D21732BE3A315F6CAA402BB2E61D40DDEBDE11276D90C2C601A935C168BE600464 +76ADED15087D54A14C68EECBBBB590927C1E10D291C9285334CB0C80EDBD392BDE4D535EB61F8E76 +41F58AC1DF5B1C5A5D91E3E27E05CAF7EC97ECF0C85B6425197AA856521ED701E5AEB82A7F52A8BD +7DC97D5B3FB5C99A5DF84D1BAFF89072922509D76BC6EDB15CE5F9EB8F4154BEE1E82020240283BD +C83A8E49AA9A2649B7955D5C058F2818A63BD0BFE7EACED4A49063C489A626277AE1246F721C9926 +E2A2B6C31045FBCD235F3CC58BC4DD6C57FE998EBD1E9FA5154652BE3A1685BCD2EFAA079A3293F7 +8142A6473822FAB627927EACCD61B3E99C3077103D2D19382BC7EE15BAD0FDE489602D055A01DBBC +F91A566974559D1B477C209416887053169C3F8F59955BE4DE82B60558CC9AE15602A93F029F6B43 +29E0E62A03982DB32F5229714EFA1491A7B24AEFE18FEBC2C93DFE50B3F641B51BDD33DA38871BF5 +243C17502D00AEA2D9E9734E80A96788D4CF5BC12A42BC386162FC88A7435EE13200C1C2C6CCC5D2 +1A03941007B4C4291BDB711446CEAF27148104BB240357D5EDA0EA5A5CE27D4A83909D75BFC05D75 +F10AA74A6DE37D7DE15C1DDA3AC3045DA6CD48323D904E716B445E5E096FCB379353ED70CF4B6FAC +102C762711079EFAF13FB74C9B47AF75F3F6BDA2A4647D2AB47ECAB64DA6CC01479F618E8D2D0A36 +45445E8744683CBBC560D47C98078B84206E90EB839B02D37C852B8E284463D4E4D890203C3D5B20 +352110034EAD6BD7F41456B807E1DB1631A9D499E52E9D9853D86728B1A2E511F40F8CA1E4724A0D +17ECD640B52FF6C66E28693D89765FC391612E5889E77423EC85CBD0A038B6BA98B607701DC0C4B6 +6B3B28C7790A1F1EB8D051DC98276DD9CFEFAB3F65C1C928E48A060C992B392A43E56EAA6DED896D +EBCE71F8245BE4687F2F1B8FC0F43ECE8DB0BD0AB0811C5CE73CBE336023A0D66168B34A95B4B0A7 +50B3BF1D197E3C042C7914FA731D7831AF798E9429571CBB977E6258244E84701E5FF91D608F98FC +3D68A4EE5B81D5FF38B6C184F6118B875F022B4CE207DC7B37E1452DFDC591A3E506AE82C7E7BFF0 +011B0A3DBD616A993FBF878FB03B6C9F2055A2B095D29361F8253C2623653687FE0AB98078F6AEE5 +FC2C2BDE0405EABEDB3A33EB7F04CB6837176245F190C6BBBCD64522B12FE7F9CDCF201A1AA8A19A +7BBC4AC064B4958F44AA0F8DDA23835AD28A1FD0EA105DE2F395385DCCFBE2261DC5A89A23AF606A +3985E5038706B1FE0910400E16BF008F250F3BDE3AD806C735495D499F16F99275010478FD2127BF +7CEDD6B5BD505FBE9BD0065B4A7090C9D27CD5B36C3AD33E1B31EB6D44E375003B51B909DA50BD18 +218418B3CD22B43278B144BE78406EAF16C7DF6B6C1C6238004AAB73736B38E168441DC16F9A5CF6 +0793A18633BC43D78674D12D38CC979F7CAADA6EFE807CEA499CB9FE616496682A66E04BBDACE1DC +112B2156B9B0B20A58A8CB43FF0EEDB99805234B9A5789762AC7D65F5A319C33F4F7438CD15E06BB +80A7A97E976E8CEC23F4C646A5821880A82B2F1DC27767F090997E91488BFA15064B702F864FCE65 +05D6CEF87D2A0A12B55BA189AF269811E3B8B850C8401F3906C080D32618D9698A766732A40A9FC5 +A94E5BDDA3D028D823D6B603B6D17DD046DE181FD989EA0F80B4CA62F7973E4DF5E032A31FE6BC8F +5CDA678D4A72787EB8253EA5882C337CDF9AA3E1E7D9536DD09B047CD8962E773F72F6418A3AEF5A +289B3406C152A50CE7BD4B493FFFC27F6AA52F79EA67E362FD92559AA4F94A2F787F6C735DFADCF2 +F08AAF98B80C53CA5607A94F25F04AA65A70A75937840E73055B3D65FB054C63E2E48E68488C9315 +A13EE949E03E46723C11CC759D222CBFAD2E1A87CAD779B23D38F7E2F660DE1388EAF1CF4D18994D +75C6CC63F187FDB949940C18B537A0AFB12AC5F67B0283CA5EFE2E764C4369104B9D3B06490D1244 +C41D6085C85F1106082EC9DB84586230511C05C82412D2CDF3DAFBF4759A775628878F997415296B +C416AC8352A6C6988691FCB831CF95C10BAE691ADB3BA2918B35924BD5C3ACAD8B137397B10AF82B +479800FE16D472CD0CDBDAAB4F882A0649CF561004B8CB7CA32EC129D0A415BE6CB91DA2B65F44E8 +0D138808A127E851A7FCF927E99DAA0EA2D626B77A16C72E37F058A3B882FC4955DC8CB6312434BD +3BCED75780B13590BF4FE8D64ACF0371F9FB1D361B05025852AAB9EDA1A0C997CFA58052C454FD45 +1E6C1F194F4D363114E312F6DC35BBAF357A32CD200A3DD9654155134259887D677ACC44F89AA401 +CA27282DF7DC3F2F04A108CBEF2558DCCE28BAC2D87B8D5B7181EA927F61977764F882626D4AB338 +D95C9477C54E9C36012A3CFFBE199EC8120A99D2D70A21F9D9A0354E4EAC7947990E8A6E0601796A +AF6F14E758CABCABDFBD8204A8E748A3E5FEBA570D36E2BF474C0083229A63F96114182321B2EBE1 +BC76DD193724C4588C1D39D184C332FAEAF4C629F2B3B2F49996E46AA6C9F497428BEA52D58876B0 +DC07B460248BC85CC16773A5DAC36CDE8B152D96057F4EFAAF8B1DC10022038577368057699B3A37 +178A9F1F6C6CC60BAE820B7ADD0717911BD23A6DCDADAFA32473491AA80CFE90F2A77E24CE2826FF +77B18B869C33FA292FE01D6477765044C7D14A548B28B1360125C6933F05C58B0889390537CDD16F +8E967E0B38579449DFC1E07389B7069AA8594C5103465D5041CC929268DE863FADB6925B350AA94A +27D421FB7FCC81C6B35F906F12246B7A5140511A97211BA9BD6831A508E963FE8BE961332F557808 +488F06EAD75E86D60DE3FA2425AE8439ECB9112BC3E4D73747C1C8E87A649919827049832DB0BF6D +A8C85C9A2592AC002809070900ECAD52A56F1BFD456AFE066509694EAC075788456B0B0BDD7C192D +321E9FB6AADCAEF00F570F22CD4A5322FBCE8FA98FAEB681940895426270BB4319C11DA67D88552A +7373398AEC5DA7C9CAA9F3B34581C6E968DAAAB2751CC012199DD897B448986CFFBAE4D412BF9ECB +F46742715A9569932516259D3B3A5431CD7028E42FC751C434E2B714C718202BF02CAF9B8A2075DE +922322EA7CFA605C8376FA958B8FBE43031E1026FBE6126A3775F643EA67EBBD97F239FB3C435526 +75CD08B19CA5EBF53B40D728556B4481C7F73EC71CAB0F89E34D60C69B272FADC22E8E7BDC6210DB +09FDD913E209F49FD28E8712B8508904620250746CA3B21B026EDAE60A2822F59E912E626B93E0D2 +BFB3230DFD0E54E91A1DBA25A609B64D41ABD897A5D21764C351E85F9E87BEAB9E645149AD32AEEB +B3B1161032C701647115F98C1C2AAECE871862D91D321AB90F3E923B1FDEE00D927F897AA9812373 +6536E2E0700F10053D7E6C589BF66029D794883EAE4C8228941CE96565B50D48887B5314A2E55379 +59638222A6CA54C77CBABD460DAC11B063519AE4F50D93DE41763BA7CFBF4C7724360E750478EB62 +8921DAA065858341958E4F3EB5966C6DD77C05EEECDF4B5F6CF19AB507589B4219377959BD258EC9 +21C34FE1DB003F7D0FEA3E2FD6F5DDB0A2D62CA5A2CD3C7AB457DFF25094EFE04A9E1B9CE7AE3F30 +026B1CB039228D309A22899F6E9B9BFF922E117123347967D7C62C670E2C74579C35989925603022 +C17B1DCE378031ABC9B4B437C7B6E64620932E93189754C01D4B280B8B08699B2CA953AE4823BB9E +E34133C5C95B3290E1BF010705AD852C72BE87291E1034B09F44A95B6A2F83FEE8841DCF661770AF +44D0AC7F9CDB280939FC5D953D525E0B41B7BE188D5C794687330CD770D24D9CD53B895A253004E1 +8A31BE4E82B384 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndResource +/Times-Roman-iso1252 /Times-Roman ISO1252Encoding psp_definefont +/Times-Italic-iso1252 /Times-Italic ISO1252Encoding psp_definefont +/NimbusMonL-Regu-iso1252 /NimbusMonL-Regu ISO1252Encoding psp_definefont +/NimbusMonL-ReguObli-iso1252 /NimbusMonL-ReguObli ISO1252Encoding psp_definefont +220 265 moveto +0 0 0 setrgbcolor +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<636F706965292E> +show +295 383 moveto +/Symbol findfont 50 -50 matrix scale makefont setfont + +show +370 383 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<4D6F64696669636174696F6E> +show +671 383 moveto +<6475> +show +763 383 moveto +<66696368696572> +show +934 383 moveto +1 0 0 setrgbcolor +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<534D4553485F5352432F7372632F534D4553482F534D4553485F4879706F746865736973466163 +746F72792E637878> +show +370 443 moveto +0 0 0 setrgbcolor +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<706F7572> +show +479 443 moveto +<72616A6F75746572> +show +653 443 moveto +<6C6573> +show +726 443 moveto +<6E6F7576656C6C6573> +show +935 443 moveto +<6879706F7468E8736573> +show +1175 443 moveto +<636F6E6365726E616E74> +show +1411 443 moveto +<6C65> +show +1466 443 moveto +<63686F6978> +show +1595 443 moveto +<6475> +show +1662 443 moveto +<6D61696C6C657572> +show +1846 443 moveto +<74E974726168E9647269717565> +show +370 499 moveto +<6465204E657467656E206574206465206C61207461696C6C652064657320E96CE96D656E747320 +766F6C756D69717565732E> +show +294 601 moveto +/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont +<23696E636C75646520> +show +520 601 moveto +<94534D4553485F4D6178456C656D656E74566F6C756D652E68787894> +show +294 645 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 689 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 733 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 776 moveto +<23696E636C7564652094534D4553485F4E455447454E5F332E68787894> +show +294 820 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 864 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 908 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 952 moveto +/NimbusMonL-ReguObli-iso1252 findfont 42 -42 matrix scale makefont setfont +<63726561746F724D61705B944D6178456C656D656E74566F6C756D65945D203D> +show +294 996 moveto +<20202020202020206E657720534D4553485F> +show +747 996 moveto +/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont +<4879706F74686573697343726561746F72> +show +1175 996 moveto +<3C534D4553485F4D6178456C656D656E74566F6C756D653E3B> +show +294 1040 moveto +<2020202020202020202020202020202020> +show +722 1040 moveto +<2E20202020202020202020202020202020202020202020202020202020202020202020202E> +show +294 1084 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 1128 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 1172 moveto +/NimbusMonL-ReguObli-iso1252 findfont 42 -42 matrix scale makefont setfont +<63726561746F724D61705B944E455447454E5F3344945D203D206E657720534D4553485F> +show +1201 1172 moveto +/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont +<4879706F74686573697343726561746F72> +show +1629 1172 moveto +<3C534D4553485F4E455447454E5F33443E3B> +show +295 1289 moveto +/Symbol findfont 50 -50 matrix scale makefont setfont + +show +370 1289 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<4D6F64696669636174696F6E2064752066696368696572> +show +370 1349 moveto +<20> +show +382 1349 moveto +1 0 0 setrgbcolor +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<534D4553485F5352432F7372632F534D4553485F492F534D4553485F4879706F74686573697346 +6163746F72795F692E6378782C> +show +1651 1349 moveto +0 0 0 setrgbcolor +<20E971756976616C656E7420434F524241206465> +show +370 1405 moveto +<6C61206D6F64696669636174696F6E207072E963E964656E7465> +show +906 1405 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<2E> +show +294 1507 moveto +/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont +<23696E636C7564652094534D4553485F4D6178456C656D656E74566F6C756D655F692E68787894> +show +294 1551 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 1595 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 1639 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 1683 moveto +<23696E636C7564652094534D4553485F4E455447454E5F335F692E68787894> +show +294 1726 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 1770 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 1814 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 1858 moveto +/NimbusMonL-ReguObli-iso1252 findfont 42 -42 matrix scale makefont setfont +<63726561746F724D61705B944D6178456C656D656E74566F6C756D65945D203D> +show +294 1902 moveto +<20202020202020206E657720534D4553485F> +show +747 1902 moveto +/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont +<4879706F74686573697343726561746F725F69> +show +1225 1902 moveto +<3C534D4553485F4D6178456C656D656E74566F6C756D655F693E3B> +show +294 1946 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 1990 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 2034 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 2078 moveto +/NimbusMonL-ReguObli-iso1252 findfont 42 -42 matrix scale makefont setfont +<63726561746F724D61705B944E455447454E5F3344945D203D> +show +294 2122 moveto +<20202020202020206E657720534D4553485F> +show +747 2122 moveto +/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont +<4879706F74686573697343726561746F725F69> +show +1225 2122 moveto +<3C534D4553485F4E455447454E5F33445F693E3B> +show +295 2239 moveto +/Symbol findfont 50 -50 matrix scale makefont setfont + +show +370 2239 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<4D6F64696669636174696F6E> +show +651 2239 moveto +<6475> +show +723 2239 moveto +<66696368696572> +show +874 2239 moveto +1 0 0 setrgbcolor +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<534D4553485F5352432F7372632F534D4553484755492F534D4553484755492E637878> +show +1843 2239 moveto +0 0 0 setrgbcolor +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<706F7572> +show +1955 2239 moveto +<72616A6F75746572> +show +370 2299 moveto +<6C6573> +show +443 2299 moveto +<6E6F7576656C6C6573> +show +653 2299 moveto +<6879706F7468E8736573> +show +892 2299 moveto +<636F6E6365726E616E74> +show +1129 2299 moveto +<6C65> +show +1183 2299 moveto +<63686F6978> +show +1311 2299 moveto +<6475> +show +1380 2299 moveto +<6D61696C6C657572> +show +1564 2299 moveto +<74E974726168E9647269717565> +show +1845 2299 moveto +<6465> +show +1910 2299 moveto +<4E657467656E> +show +2073 2299 moveto +<6574> +show +370 2355 moveto +<6465206C61207461696C6C652064657320E96CE96D656E747320766F6C756D6971756573206461 +6E73206C612047554920646520534D4553482E> +show +294 2457 moveto +/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont +<656C736520696620282054797065416C676F2E636F6D7061726528944E455447454E5F33449420 +3D3D203029> +show +294 2501 moveto +<2020487970203D206D79436F6D706F6E656E744D6573682D> +show +898 2501 moveto +<3E4372656174654879706F74686573697328> +show +1351 2501 moveto +<54797065416C676F2C206D795374756479496420293B> +show +294 2545 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 2589 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 2633 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 2676 moveto +<20202020202020202020202020202020202020202020202020202020202074722894534D455348 +5F4D41585F454C454D454E545F564F4C554D455F4859504F54484553495394292C> +show +294 2720 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 2764 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 2808 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 2852 moveto +<2020627265616B3B> +show +294 2896 moveto +<20207D> +show +294 2940 moveto +<6361736520353032313A> +show +294 2984 moveto +<20207B> +show +294 3028 moveto +<2020736D6573684755492D> +show +571 3028 moveto +<3E437265617465416C676F726974686D28> +show +999 3028 moveto +<944E455447454E5F3344942C94546574726168656472616C20284E657467656E2994> +show +1855 3028 moveto +<293B> +show +280 567 1 616 rectfill +2125 567 1 616 rectfill +280 567 1846 1 rectfill +280 1182 1846 1 rectfill +280 1473 1 660 rectfill +2125 1473 1 660 rectfill +280 1473 1846 1 rectfill +280 2132 1846 1 rectfill +280 2423 1 616 rectfill +2125 2423 1 616 rectfill +280 2423 1846 1 rectfill +280 3038 1846 1 rectfill +showpage +grestore grestore +%%PageTrailer + +%%Page: 4 4 +%%PageBoundingBox: 18 18 577 824 +%%BeginSetup +% +%%EndSetup +%%BeginPageSetup +% +gsave +[0.24 0 0 -0.24 18 824] concat +gsave +%%EndPageSetup +%%BeginResource: font NimbusMonL-Regu +%!PS-AdobeFont-1.0: NimbusMonL-Regu 1.05 +%%CreationDate: Wed Dec 22 1999 +% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development +% (URW)++,Copyright 1999 by (URW)++ Design & Development +% See the file PUBLIC (Aladdin Free Public License) for license conditions. +% As a special exception, permission is granted to include this font +% program in a Postscript or PDF file that consists of a document that +% contains text to be displayed or printed using this font, regardless +% of the conditions or license applying to the document itself. +12 dict begin +/FontInfo 10 dict dup begin +/version (1.05) readonly def +/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def +/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def +/FullName (Nimbus Mono L Regular) readonly def +/FamilyName (Nimbus Mono L) readonly def +/Weight (Regular) readonly def +/ItalicAngle 0.0 def +/isFixedPitch false def +/UnderlinePosition -100 def +/UnderlineThickness 50 def +end readonly def +/FontName /NimbusMonL-Regu def +/PaintType 0 def +/WMode 0 def +/FontBBox {-12 -237 650 811} readonly def +/FontType 1 def +/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def +/Encoding StandardEncoding def +/UniqueID 5020945 def +currentdict end +currentfile eexec +E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89 +699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641 +2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2 +5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF +9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A2261C63C769D2F4B60FA2C438AD7D199D8E4 +5F7E7C9A605C8CA14E21FCD81C9A515FB8DB6F99604534D06EA9D87FE0FAA852899C9D0595C7A97E +6C55F79FAC45CD38E87B10D210CE7501E88C8FCD3444354365FB893A12F596AE2C1E70D5819EE0D0 +87D10BF8DA96F3DABD5405D28C4228C6C31BA4052464859640933FEEFD8071C0C84CDD829A9B1D0B +A01F25A4D50EE2EA2B45160CA6333B2D2800306ED2BEFDFE155E9D9F9342EB8D5B0ADBF2460CCC98 +643FB1287CCD28ABA7B5CAB92EC39EE2E918990372B16F8487EBA30EAE88708B6CF33B6C015D8096 +C7CFE2F139F52052E3925C0D50FD64CE68236D59CB83EF56BFC584150EC38065059F3308AD6F9A99 +F83EF4E6CB13855C8175E31417D190D036B387D3952344A950F4D8C7781B307A094DF1ECAEE4D2C2 +FD747BC6F7F9C6BD0E90C19294F96C8C5CFE88FB34C477574A1B1630B8CC591529E59B20794DA32E +61DECDA8ABBD1AE956CF74012AA01D42EE01E861B0AA6897C864788AE59DEF43C493246FDB1ACA55 +4C12594BC7B33657A9ECC9E3D1472EF826073F632BE540C35FF6FB40566773F3BB2204D3A579A08C +CBC844C14B18C350F003B9DA23A570C362D6003893CA32F86F59B829C78EE3188B6E3F7FA81D7F62 +2825C639638DFB78B7AF1F500F5B450FA54DBFA5CBA277C794ECE93275A3DE0B452FDC8DDC2993BA +A42F28A636008CDCB03EBF71BDCAF35019778993443F88412AD2AD0D7155A3944606463266322DBC +0244B07DA1E9C27A27B59664E8566D7A54CC03E995AAD008B0A17E2C3EF61F720CE7F7788599C4E4 +4C709CD5C31B11107F16AD70B17B9AFE2E8CD922A7428DAC171427FFAF51067307FAB0ADB530E701 +FD22DA22C4CD3064067BD4F6089C4B2C87937DD426E4E9D2F60E608288BAC9056554D04947E69200 +61E379CF5E81BFD32FD37EFAC1F61CEBEE551B0851516471A7472C60DF89DAA9EB1DC5A67E479745 +3E69B9E22BAF4E3CCA4192D603295B018C4AB69D18DE52DFDF15E96B557F290A4B8C5B1E7A6CACA8 +1F2351B97ADFC36995ABA43803A6E5AC04A3C93495F6D38106B8B144449C07D1358210F9176E1565 +72363CFBDE576BFDF99FA329DD1346E83F79E06CF68250CA57A68931BC7F342AD295D0CBA17AA95B +B8EEB53EA6E8E660B814E9F857CECB14F44A43288B69A9E7908D55BF19E844359879D28CAEF1C38A +36420185D20DFB32C2E002202800E8EF3D67C5D50E919657CA958B538D537D503444865331D79BFC +40312068D72364503BD0CC84B5F30A74D8B5B6A26AF2DB764564FB65A6BA8F9051AE2B4EA458D46A +4569F30C6E77DC097356770362E6CF3F1661074778EBB44FF7D1E3B64FF75E77E11FE525BB121C65 +46CFD13300CA1F02D571B82A5825E6226D14FDCF27F06D87452A8B6C5DCA658535CEE2A795E58137 +D48E566B69D53A0C3B766E84C51EAA221C46999CC8065ADB2F129D5B630FAB1814C0C33B5AEA0EFB +B6E994D80941B53079AF96D90A0B924F9B0E319BED9836B8F9053F868363D3CA554CBB181863301F +8CB940872ED5FA7BD18CE39218B5AD8AC57D0F752D941076B1C64D99BE0DB86D7A6D96510D772EB2 +4C587F11779BD21CFE5BDE1F29C1EF9022B2B8BCD7F91153C845906722477829C40111D810480F3C +F62DE8DBA7FD86CD236E656618CAF6FC46827FBC4898EA7672F8C9971AFE43E0E01EC8B77D4AF48C +BF1210E98C1DB15C16D149BFF58AB0270CF015B107A3A50F5DC8F37FFB92EEC8CB6778DDB7CE4AAB +C464C4AFF654223006A550EB52485A23D2B4AA7198D3CD54418102F1E9A4FBDE37B841E56F5C2C53 +966DB9B66B000E4588282E3FB80C2C519339F0002D2F83C979EDC5827A3B3C8EF8810A0F9DACB6B9 +998E9AF6551F56313DC4011904CB979AA2D32B11A811BC248141E4B9734D9FB7982A5671002D8279 +CAB93ABE057474628DEFC95D43890DB1ED34CFA8A20BDC3D874E7679A396158E522ED0AB969A4E3E +C7E4474E192590504D54DEB7B260B7935C4E56548A7D121AC1F741F8CDF259EA1B5813175A77A1D2 +D30BA26F65EB765A04C09ED51F69F41551ADF399E6AA2FC09788137BEA4913F17B8EB838C38FB272 +1FDCB55FD65697FF0B850E7D3D1CE266BF90F7EC06A9A0876BDFE767D3A918B092FC78C775F945CF +1F96E859C03DBF630D9A940939654C3549D8F7921CB94EE23D5A0535DE9DF31EA0F937F860B4F220 +A99ADDFC343D7CF7BFA0B803C12C26403F0DCFFC8EA786D0D8A8D9C367419CA8AE41190CE93A8086 +583A1E6C9D70B612C84D87D2EEAA71EC2DC12F4CDE6A821303D5F6A9BBDB7EEDCD289E80FA3B75F4 +7F481B50719DCF4A142069393593B9AF9CCEEAEC56A35B8787193D7C88113E9E1E221D151E093B01 +9EF89F6118BEC4735103CC8003CC5AD1B6727B3226CD44C497DA7052DD681695DBEC3397F9598C91 +77701C73BF0594CE93F23D50EC5BEE2FB9DA1FC966DF148B27B28EE3C89526DD6625E2887F9FA076 +7C127C609EE315626BC14D274FBEA56528DC06A27B2D476D46E9E7916590B156A5DF04A6CB15E362 +45D77021767B6E5BDFCC679670263FD891446C3371B11BB6E1DF60F960AAB4149D7753E6A5C33810 +C42C8BFF4E935003388506F8278BD7CB672F132E065AE684DCA0B9064D01DD620E7FFDFE04F14277 +EFE8E60159BA0FCA3FE2F28B902D4AC275D19F0AC6971EBE827C4A232D87650D2688345BCA78F879 +077114F0463C5F058107B669566F8171E4E284D278405580F04BFFC9902784216E0C9A17AA9B2935 +E66E18A783F723BE044389B7E9D62AA36818FF2EA406C3C1A9D2F3436F3EE7DB8BE86AFA8DAA6A4B +1B84611350D8D27605509612B515E16AA843164D5D0805E36A2B9EF74C5F6A0B9D59A04B55697123 +27F4B1B30E9587CD103337639967CBDC655AA46E80D2CFD24BEB50815B5338E522B3A7AFE8362AB4 +F05D8BC52BBA9C5089ADA8C89529B0275AF422EB540D31A938B8740860756325B966B36817115213 +FAAF92DE63F6BAE1E0064BFBC5588098B61EB83C71F1C2082436D37DAF1ACBE186FEDC4BE7C1233B +6F18BEC5F99002D21CB7864E4811F7AB3C03003E1E4490AD1AC793BD28FCD5EF0E6CC30EF39A08C5 +2F71939B0CEF620DC69E31E39D6DB969049031B0C92EF2DB653D97F370141456A52985076B268652 +FA2648C792780BAD637C4D7581FB2D62011D57E293719487CF2D1F013CFAA532E1C2D39178D51272 +A6AF041440BCA174B5CC902BD7390C7D3695056CB4BD7791F9FB6D88E7A70DEF2C97869F5DBC5BD8 +23C517C7B7C39D624DF627DC9653EA5347BFDA80B723F05F6DBB4C9EA501D862ACE05B9DBDF21B70 +56FBCD8C6D4B85873DCEE6166C8B5ADC0316CA12D9639F361B15A42F00E1D62EDBCA1111972FA0F4 +5758BECB31DB38316F3CDFE1B41748C93ED58B67E9B57ABBED5924A6D53E99FBC9A994A6489A8BDF +13EB685548B4DC6D62DA7426C22227D4D43B6FFC7B5EA91C896730253E8941AFEE588359C2BECF6F +FC415B9EB6D31CCB0F6C7F85853E6449FA6D627A97A3CE8303F148393ADCCCDFA2FE085C6908BE5C +3C05AF00A6F02840206C3253A559AC5C049BDDFD11AD9B118403B84DA10AE3C470CB9A9A2D1D7B73 +2F59F5FE146DEDA60AE750F551AAC934621B4470E1BC324C436303E25F81D0DC3188BE0D6FEC5414 +C20E4CB18952E12CB6423DF7124627ACDE145500D77A97A8BFD9CB50D1FAA008E2CE2B2505A4749F +1EBBB092C347023714055A9B63353AF9E7FEE05BB54C9843698101F79888A91531773830C2C967B5 +88D3ACD2192883D5CE3962D51084FC653EAE2C5FB2DA41DACEFB5C76812D2EDB5B109677289CD199 +8D457FB1023A19AC67295BBC1A9A20A426B06A368DF3C5DD083CB1180D287F5500F2C635EDE157EE +FCEEC5503447382D15C748C1E35F68753992E5C90F900DE54D18F8E1B355D1076ADFB1F3590135FA +D1A36F028E44F48ABB149B80CA9A54614D467F8D71CB310BBC7AC7100261092DB8C5BFD39E0AC6BC +2C9D6CBC3A8C05FF8A74CB21608EC4A4CFE4CBAA2D056DBA14206106044DECF59F957EF8A9CADE4C +9B19D8D30DD4FDE6A9548E50DB51ACA73330142153FC36B69C1C8D5B26D0C689B7040E81AC2C864F +D7C097C99BE5953843E172C97AB5684F35FB03A725A89DBF371F08DDF40A1531FC1B676DB0E1543A +EC6E97D3D2E4AA3D5831D8B3C952ABBFA112352814FB6FAB61A0D680E6640F6AEC8426200CF61286 +F7422CB2F78C61EBAA36D47EC16D7FAF8B4AF31D090CDFA255D9D7C61D46CFB22A7D6E1758E71ED5 +67E00CBD8E8F468DDFB477F091A2F915627F22FF47B876544BC1F03B6BBB98385F009C20BB1AA2A7 +A78674692B8EAC2E3C8069B79E679338DA57F72976810F845BEB6B9ADD32B95D78E5E60F16DD1668 +9C05FD82D36A3115BE8ED494A74DD211D58A2CDF983FCB9CDC29BF7F0E29988FA23560EDF514BC1D +183F3B2A22C09FB179B47E05ADEF48DF02F31C29875D1915037B19407764A4292FE44E741651A8E3 +BEB5F0D972B6327090F664417C84F84FFBF0AFFF8B1D85C822D90730AB4140C42A51AA8B1DBE4398 +4EA8566040EB8B341CCE23FD3F69DD235A080BA5C69AECB9BC732BC2D7D40617DDA6B79FB6EE40C3 +556C7DF9B23DAD89E94054B1345DB8402AE679FC4655A4A776C0150463F8DB2BFC0608EA1F124E22 +1DDAE6026B5E5D007A7E4A0D6B3B0CF3A2669E67C5E4F01551966A7BC48F2F4B6A87E740D8095E63 +F77C7A027F26B52F2299DE5B8A2F6209BCF3D31CB0235F998F781E5CC81E31DC424E008D46EC0920 +2951E5684804A0592EA47D6C788A20487BEA2EC8F2E6C1D7F378B62DB43CA43C4B366F8B4319631C +FE9854F0E10321CFA3B01C873584863BBEFC23C72C05E695B56E8A52E89AA2DAB543834D34DCAC5F +ED08DC51825C5257AE59850D101D84F4CAA1D29FC932F9E0EFFBF7A9A7F3685F61F0490CD3CC8988 +2DB52A757A6AF4C4E67B407BD2316B1C0FFE7DC54E43C87B874F57E4903334E2140B011484863CDC +ACA331175F2CF3D72E0042855983AAF8853D3015E870FF0807014C31D55060DF3FE1FCE157324481 +2744AB51322444632F9AFDA6706E320FFE82B8CBE242A19DF00CE73EE48E25FF49D5871BD3E60652 +298FE3E8D400609E232E0DDC794C0579ACEF89E841B2EDCA50D51151F65E8C1CC3B01EF1870558F0 +BF5743718C3E068617E81BFE120C6CA16E0924BFC2541177D53671CAA3AB641C41557DCDAE1A3461 +47B5E999C4541B08B4AFCBC187AFD653D5B5F8386DF6AD8FE69E21BD0567DF494F736C6A184FA4DE +48DC9F347787CA96E2E00A296C2DA05C2AD9BC423E9CA428D7F1FA12DC9353A302FB8C529AF8688C +BB543B45B2717EBF8F6C497935F4F3BFFD285E0402AB7544B3CA4643AE5A8B5250ED987A95FC1F27 +5B9707ACD0641BD0EE2AE9758494F8D8A51DCE408A38AC20EAF0852D72D84D0C6BE973326793AEB9 +55EAC6FE0A2813A355DCD22F6F2CE56588D1C055CDDFA98878BCEB6A018DB22922D2B600A20F8184 +2E665DF41013CA0947C4237C2BD60A75E2FD1A3FB8C8FA19485730B87461AD466ACB02DF8CA24091 +4FB090B3D2B41EB6B8FF05E1A59D9FD668AF70BA5BB72778953BA55FC5F9F626043450E1D09BC83D +8605098ABEF884639A37809A32565CBEFB3FF39EE53D6C18C58C272BB928E4410E361E59A50F242D +69747A032617C52DEBBF62364AB5A96EFAF642D9D82BA679B1D70FAC10A4EB62FA5CFC308E86368A +AAD7E75948F43598CD1C544A0D4091374D7E88D4522CBE902391641327E888E7748FA889DCE67ADE +61699E7D77763681CAEE9B1CA8837B2F7EF9C18CBCC538C465C8E2DD34616953CCB6030A222C728B +834911C1A179E2C770289407AB28B303E724D97F747D6134B425216A64C6E0B60F633E2B85300047 +E4C90339CE030A0FAE31E830C8ABA5AB3386A3B69267351A7BFDD66356AE5E57FB2994452993E90D +E7C4E260ABAB93C37831856A650D56E44172FECA01D6C7C380F250B82473960D2A2A5FB6B4DA668F +46E624ACF7FA0FD4490F485D640A3ADFC9F8652E7A38CE5799F770C3606DB4B8B947F93967F779E3 +A3C0572F13A5A187D31D7BD12A5C7BE23CB6ED6192086241B76C5BA6983DB9C93E4B208D707D3760 +F03CD6272EF3A4CE89B8E52E6AC5871A3D03EB975759AB4BE239E5EC7842CBB333E692CC607C722E +185D3C39164DD320C6945629C70FF66A5237C0A9520A1FAD6EB9816069351AB0F135D90CC0982B14 +7D2294AE4A38A527EE40BE9CDE2512AAEBB590E134388BB171D0956A7C4566D65A9A041BE6C4F883 +6B3EC3D2ED1B48B566A783292B15B6127920D247D494F070BB20BEFF60640B11B276DDEEE49706E8 +B2B21BB40B7F00AAFC594C492C25DCA774E0B80D82E927448DE2E74A9D0DC7AC9260096EAF187B6C +D6AEAA6D1DC4205B4411122751A5B22688404EA7C5861730371FFAC10F5AFD4727A0E402AB5EA757 +606B75EB86A05E8F774D6E430A1A3FE2A37EBB06700474239FB1CFA05EE44B91B82244C575B52E7F +AF934B04EEB0D933FEB57EBE326D75821C8B23EAA85B583AED4320B7F04B9F2DC591091216FDE52E +064BAAA9C2C9D9714B95A4558C21F3CEBE624B5403B31508F178581AF6863083ED762F1E2E34A45C +FDD71660D626FF8648F5D6C5E580D4765A67FB6159EC8077A9F0A88038C8D3D7C77FF0926E2123BE +874F7BCAF129D55A5B5960F824BD1728ABCFCC51D23936DE9A25C408D786E44C3A2BAFA4423177AD +060D21D38E15E23EB6FFC0B4120E814695D423EEFC2744A1FC81B4DF89D76F0A6803D8B14E75538C +AAD03A72517B86514F6952F6FD619D9E910D980F00964DB325318C045BDF79647F453D4A5CF4E61D +D5359782827229310405FBCF6107C3AD9DDEF9A9A339D5D5A6EB2E7838A0A43221BD62CBDF732DB0 +A638A52016FB35BA7761AEC846A023D3BF2D1BB183543E81EB7CAC1E5970CDC6F068C5EA118C7AAE +528D1396E6DC939112DA4460C890EAD5C01BDC438F5BB734218BA6270ADD0DC1778FD8AB16831D6A +302B814A1A44B07EDC65956C9E6CF4875DF521F3CE5B422F71081B6D69BD270F739095C9E81C0377 +934A8BC6390C420C4E4CDD9CF7E32544C68D884E15ACA3BCC07FC8C132D8FB9D752C15D75C52C288 +57E2EA461A6FCAD90C56843513F74461F18D7164BC597A28AE4BA7C86EE1703535A9B9ED50122627 +71FC12F102E800E0E1AF7BB46681BD2B14B614CEA91B7B2AAA35235DE76C0E113C92688F8EC81277 +D58C3406778E1EC1CC15F1CD9A137C8FFDAAB99ACE3BFC782916F1A877170589A92DC921E6740A22 +B84DC6BACDABCC76E64C79E3A588D80F8F4D376E1B426F15751CF7391102102F0AFAFD8B22DFDEB5 +48AEB5F30B1673023D22054A13391A0EC08DE6E7B685A0D031AABF20B7C62187C0284892D5EAADF1 +21BA28263EB863D5E36EA9C06A77CCFC0E17F593961591F84D82AF823EFE41044C8D606FEF83CCC7 +B0E961E7994DF8A3CC36B209D953E250ADAB8D22D7F2B4E2C9CA39EFA2D93E56195C1560E30A5190 +CC5B17FAEFCF250DF79F6B624A4B917E11C332222FCCFEC4F6A47BD9E75DA9854FC3F7AE554E91ED +DE144D7AEF38A0E3EDB5E5A5626374DB94F022C8CF549093041DE00D7269B7CE544E748439BA2870 +718C08E58FB4A77D93EBC04B7957D272AE1601D41BF85A2BADAA0DF73B0D3841D4839C85677FB2E1 +5F1D6CE592669FF4BBC9C69DBA334DC37706F2F6BE83D5863E8CD6A30C08640AAC4C233684E66B4F +E6B62D4A8BE9D531E47BEF5640D9B5C27D990092BE1597F6995C8A77BE9C18AAE6C1CF130775DDAC +41D34438FC7AD8E042CB56CBF2944932EBA7D053E9376FF398367450E35A1945FE23E05C921096A1 +5454721FFD0F429A3E06DC3ED36F1C170BE79C66996EF8337AFF85B90C5D3A4A94455AE9FA32E211 +7A63E59001F052D5F6223125BFAFA40901E98960ADF7BB886729DCA82FC3B8CC52B37FF2517299E1 +D769057F8154FB95582F02CB0BECC873A9C71796ADBD3E91324FAA94F2C41CF57C30B5897D031C02 +D256C909E080E70BFD1F32E69EF67031138C2DDCD1A8E4B65E485C23C3E450ABDD9815512D6F34A8 +4B9DB715DB2C7A93BFB424316E1AA44397749CB01088428F149A3B4324737ED9957FD388248462AC +1B2610D72BF5C073ECA567E7385CC959E37CAC7E05470160FFA5A9F63B8E9B082937E911586EA165 +374938F492EDF28CE6020953A5B5CCEC7737F9D9CC8538C4339567AAED3794ABA3B9F4EAE65466E8 +E326F6C399B36355935FBDCB9972F10B13494DC25097FCEC5A6398F275C8C151558E74C5175F7BAF +4155E36B733F75CF9D5C5979B0764F14D8306E06BA24BF791141E404C69F3F8FCCD91B9C58C2C671 +AAE7D4F9E5D6414E46ED633A5F78AA5BF04E652246A066EAD9E582B181CC196EA2D3CFAA383B5D0E +4CAC9336E119C08CC6AC55CBFBAE147C623B400453BBF447E96DE036FC025624384359EED7C7D5F7 +858DC0521377CF647A157FC3F188DE5EEF094DBA125510FDE34C570D7BE76AB5DF0A28BF45DDAADB +EA7EEEDB936332DFE93081E0AFD3FDD46BED08D6914B2EFCFDC41662A33B90B03D76D34F48D30FC6 +BBBB600E90E6AC7243FDF026762A44B4D6E4ECBEF48C9D7B696AF29EEE063E557D8FCF0F09E0136F +45D17E608DA36E59F2AECF8493F8D62536119B5F7E1554DFE3F6E8D7C9A2C6F557D18B4AF92C9F6E +050975C3B5C54F9B5F4E39D600B6FA2CD6DE203A174028CBB2A201AF126D1013C229BB82CFD013ED +199D01E51EE2780FE896E01C63C655087A3E61A7F1029FA5E97EA1872F1B45F22282DDC317E17926 +7368CB52DA9444F6055A3C653659CAD2A1D8712BC2B1B32C1DC6906D957FB88524EE066156ED6BDE +B8D832F9338F9912E29A250A8C4674E667C1C278B677AEC9972BE83CBA3FB779893FCB8F81A323AC +91474BA2A2334A07BB5628E905C518E634F6761A3289056F83D5DD7B3890987EEE1C18FB2D379CC1 +905F1AEB3B3D2AD578F0D6C845D2D40C4BCEE3F71C90E68E5417BB8CDDD878D83BA80AD8485F4067 +E5C3CABF28AB56CBB219C0AAB8FFC6C7E192BEC8CBCA1459AE4450AFCC81B9548F40CE2622E5A7C2 +81F74DCC02DAD57EFD92D072318DDF05BF42F1EA8163071E23949B0179CF7DE64677CA99B23CB926 +B3E294194EC13397EA1DC9A5E1CDCD828156CD71F81B64167D4FB01E6002713BD8AC6F82B20CD369 +9C6CA4704DC5C65A2D66EB155B7AF1C9BB46469416FB49C1C7E17A30A5F045271D7DF3FFF2F42C6B +470701C381E3456A500C6BB3D0E47B4D91C5F34B49BB6272F1F8698B307D89EDA3A1565DAD1C0864 +627560CF922DCF5B34C67860352390B282F95394AA2CDE0E97CE3ED39546A6AF1C52BFCF81A29BE8 +2C47C99E8050E4889E4575B75F39E662F2DB7420673797E2ED3D67CDA7AE2C15D0A0A794D57D168E +BE13214E89E0209AB2C0EB7784E9491AEFA3C02D0DF3AE5365A0FC4AE023CAB528162C7A1B173664 +9DFADDACA8DA5FA18B7D6489E4229E9E24D38A620464A744A5C60F6F9D334B908706B738AED18669 +8A8B278341FA4D65A0A88680BA484694921512F7DE93337FC1C02BBE6E64AF2DAD07603279D87329 +1D1F4D39C1DD6D89C90F65240F4808F6F1115CA55B88E242565E59F3BBF1F10EC7B88872E9AE61D4 +4CAE185463EDFAF7DF63DE4D2207D307AFB61501892965170D2945846FCF5973A1D458607F50C15E +06E5BEC715E0C156259AAA6C735593E5564F65F443B78CC7512EC35A56F126DF9D30974A40872E42 +65E1AE5FD483CFCBBBA26DEE426CDC4721F19C3FDA86ED7AD4FA1120F63669BEFE7002B128CEAFD8 +C63E8AC09943B6CBDFB3D2476A026C00A8FF81B1F651B97F310C82ABA5F388CC1DB5AFCFF5996D52 +52A6A42FA4D972E41EE56088F78CB966F9051171C472C774879AECFFF08BFD9CEA40D7C298922ACE +64F28C14E0B81F4DCADE81D71DE3983D87D905192EF13CEE71B2D3FF1A88AEC671EC318917DF98A3 +C9054E372D22A3CEC82FCC217F47319A40900312F6E32B536B9E7A7FA0837EC65CCDB5FB0D414371 +17596CB39D9382262DE6E65379D3A9709B2CFBABF5FC5D5B352425F06F88CD31012A2A4147B112F0 +C1C0ACCC808CD625E0228EEF66661F70AF96D3DCFECD402700E4F6522AC9A856DA466D55C84F65BE +2810A1565163872D62EB81333A698ED7B68352CACCA2D7AD38AB55C19E4F5582F75818302F5FDADF +1DCED09D94872F2D48FB636C8E38C7563C72C771A08C6B1F041F3532BDB39006C89A33C09BE1E3E6 +03622D891F98010BF1DE5355F557A1E09448D486ADEF565705277B31B8BF2B86761E32631E3435B6 +88B79D566F1747BA456DDB43CD239FB47FF7B425EAA4C657C8EEC26EE01AED07CF916E77D53634C1 +37AEEA009C6B515B6342C54BE2C7B95955B1A9DA277A0ABCDA2346E88018C726F481F71D6011AA42 +F8852F2E5749518FE3B3AB668213FE1A05C10A1C53953D75312631D6BBBA01D418199DFEFF8CF548 +6109B099FE8E2F606165FE30F532C03567785D5362AA873C9D3EECEB20F1945D55F49B0CCAC84967 +59FCC7292E46938943C262D78F3212D3F9D0F7B103157F423D71B1ED54B2A603F4C269029918F238 +EC6828FFCEC66009DB9C9E59534EABB183F31D7AD4C57B1BDF0BD2CE5A421882BC10CC1BCE6A970E +2B586BB221567CCA483989DD0B8DEC424C1D1FF042DCB7834423CF244EDA28D2D969B17440CAEAF0 +24A6119DB010CE366821AFA424D1B8299609C04148275AE6E5257A7ACB3C766C747CE99CBA2D703C +F19B7CF301B634D8B613DDC4AFE4633A4D77BFF8E00CFB5E289EBBCAC90A24307E7941EC1685CBAE +400CADD876FCEF7F6557EEE167D2035A05120293527700DC510B038A496BE1D5CBAEF24ED39F7421 +1A93AADF22214ED606A80582485AFE358E3A46D0671148998A3B3BE209467009B43400870359D418 +9A8CEB4D5866AB52D16D9CEB1EAB71C07E6CAA34B70E3096BF7604C22C40D5FBFEEA616DA3BABD59 +DCDB97D883FC8742B8267A16A99B7953225F7144568D566E64542C92E538AC140C851E5D295528EB +7CBB49909B1CAF6409C9BCCEB325468FA0B5F7CB2987382616B477CCFE4F4AC79E4A6F7165363543 +F04DE5B6F6E1C2E910CDC3CDD6C4C92737198F892337DCB6647BD226C820AC99C65D8E7772BBB74F +E65DCAA8A22C33BC168BF48E40A82700A3A7668C5A9A71E397ACDFEE7D556C5C19467B7AA69C260B +727407AC837BDB7D67DEC055C1F45D8BAC61048C45BC9FB3CEFE7549EAA2992D2EDC126FF7A05EAE +58613332A2BC1465B2BC0429162B907D65F793D236EDDD8D35405866D71B25F62DC4A7E06D4DEE82 +840ACCAABC0774F8A63E9C0F7FC980B3583E7A8B01C46590E3BC04EBA565C2EA94F057D964A78A90 +EA9F52ABFD70F84E44E434BD10A42E98C794065724341F907E35D3CB257161E01C7084E3A0166D15 +CED65DA7BA87DBB2EA33D39BD99AFB93D3548358D08330E807F8552CECF63C84F805205491BA3A1A +622E70C232FADF3BF2DCFD6F0539158D3306506F150B0518371912A25EB96163D73E9EEED42EDC84 +D688BC7F7708D9DCA348FAB4DF62E5809BD094842D0A31DBB7C4B41F94D946810C5EC10B69AABC2C +91A59500B2E5D37F4755DDFB7AE4ABF757F4C5BCF77C7F95E6A616646456FE8F18407080BCABBFA5 +7704287AD26222DF91AB2613951E2D679472F8ADF06EA2A20205EC19972299A78BAC52114334470C +5F5890C2F846B4C6042D73945127F2E3910ECA1C4CD7A16EFE4B4BE38A15AAA710682C3836A8CA83 +FD384970139D8B46FB0AEBB002DD224199672FFA02250FBCFA4E649E335428FC71F50F45E498419E +DB0E970F46894A48F65580881C9C4250FCEF65C9B28699408E18B26FE6DB7F1CBDB767564E73CB59 +54C6D639CE33220C894F36E70F71C9F9AA3FE2AE0AA0E3F2E304EC5ABC661675CDE2E70519E4220A +E26FBACBD01D5169EB844750753E6CED53E3678FDCD08AB93E10067E9C64F38B40B76D99B6CD92BD +F4155A1EA5CC824998B59AAD06E09E5F15EBB2288D66EA71B296616734FEF2796F07FF0D8B047074 +A1111D68B99C2B70FC56E74A51B062F4998ACC85B1943C9477E436E5CD7AB18DBC898D21BB93475A +623BDDA71D7B895BA2D4C10F4B90BF335126F4FD57D73AFA50170F6B3C364922E551D40E35DA75FA +891762FA23401D39260F2E92C7807C746F13BB35CEF9DBF2E76E66A72FEFF095DA482A4DE8A42091 +7065736CF4DE904FB52E649A32255E2030A7B31B686353492F31C064A3C4B0448C4BFD44B8E15384 +FD809B8761EE26A7DFA1758D57CE4F0BC376EB2B3833534B15A83436BA553955ACB5A7A66796AC5B +92DB5388BC53EFA27508B08E82821E5CF669BCE52BB860780F749B4F38ACDF5FF12726BF3EC2743F +01014CDE96FE6B4C40A034E9EAFCA2A35CCC776C2669E6AD138070A40F48ED79136D7FF57E993E09 +B81C543FBADD350FF5B5F7A46F060F88E30FE2D8233832D18B6C323EE017EBC1DF5C838321CDC8A8 +4CABCAB20B60A1A3AA028F36EA6E87C850AF8AF7CD50AA6359038BFA8818821D02CEE8F51DAB8C05 +F7AE9797814D97F3DB8CCDDE45B21DBB15CEE292FAA534A5F317B357F4091F3DA357325B8B9F5EDB +45865415973C143E5E5BAA483FBF2D06CDD4246675EC58B84C6AE65CA743117FF00F229243772561 +31A7F2BA26A9115AFD96C18216CFDF41B7220ED0CB3FCC26C36380007B382A02AEAE428887DC8BE5 +FDD630AC57EE3DC156C7B8B29E687F24442E35CE10BA4087295A641F7139C831F7CCDA6CCEB5DAFE +537CC1A97C5A337D3C48A6AE947F58A30DC08CC7B58DBBB4737AD52783C573FC1E9408F55495A80E +7FDA61F0B9C4F090158F1A416249EBBA936C27BEFDEF19D1BFB839EB70576A010706D8B95657B218 +9C2AE04C11EF9E57FE09880273761FB4302C388BD608FA0C7F00F033C9C00F4E3D5CE2D903E0DA52 +E69C7745EE9FA75E2AD93DC6CB5CCFCD3782A699B807AFC36AD1F62B05856D5DFD6F88831B90EB3D +CD523582A49732E3FD7253126D39E8AFB8458B5F7AD7F94A8DAC13365F433C857AF4A42C0A08C4DB +9887C4957259ED22D13CFDF5995DA957EA5A0F620B0214FBFE08AB6D552DBF048D62CEF6EFF12F15 +3511ECA7833E0E3E95F85E6AC0F95438AC4C126E1F1ECF336ED31CCA7EB216D279877123FD9FCD8F +B5E52B587CFFC4428456DDCA816819A8A4A211D8F1629E5D42BA4C5C356E580C8A22C61D987552FA +A97893816DA73D423686E4EBD44375C257F031318865A20F22115E72BF1EB9F93AAA169C140A33A0 +6C35BD4526A38BE79CF40AD1EFA10411E8F3300A8A8B97AB140EE6734E1BEE6C8EE443D698D34159 +97649C6F10F20ACD80236422E215E146D744A262DA3FC88DC0D86FF66512F49D3F957D3C5CFFEB42 +4823509F33F155057A4C6F37B52F4667767BA94F6B8B62856B553F307E5D230C44CBFDC9A97A45B1 +39FFB2F2565EB0E22026972FAD0FB7B9576FB6F368B61979943A398773600E7EE1DFEFBF26D45D40 +BDA66EBB96A56EE9CAE0B2420C5DD83E24DBA9FF885BB844BF3D2BF93B07325DFF60C0CB5FDCCA0A +C8FB5A2E119D5AF26E53AB8E3B428481C2871DDA26EF0B621CD8572B3C664BC7AAC01A1D05B98F79 +1A7080D294BE81099BDA7982432F3DFF4775C44D23F4F1B2E0162B61A8B2CB5EE8564BF98E2ED403 +2219085FE6194C19DAC98A421826CAED7F1AB1477AB327506010217283894235D7DBFC1153D5ECC4 +8AA7293F19592B4D7E95FE55151889BCD1D7FA7DC2370D2DFE11D7E4EA34B5C7A8E73BD3A348FD38 +9EF45B6167FB90BA44C23E912F9A4F2FC0427ED070592F7110183BFDB2C400393BA7569058227926 +351F07FED4F33633BA03A72AA2DC6B598E49B96021DD868DAD0F352E5722FB714F667C15C68D49C0 +3D822D82677EDFE86FE9668E537DA284068C9B0AED83074C92A5B939296D505B837E6A9DDAB1AEAB +7455A08A114C2222B339284674B74BF4CA9EE0C020BF2A148B439C71C6BE51A94CB64FBE4A7EB295 +5A455047CF5CB348B062ED4F6471CBC3E9ADD9BE9B96879AC7BC71BCE02FD02F17C6063985A5E898 +3D205AA1489DA13C408990ABA1C54F2F501AA172F530480D789C848118C0A74EF98D5F607A067BAF +F6030D887AC6A6497F9A0B38F9705F328AAD4BFBB634F739386177B07F22D5771282444E5EE17335 +B4D0EC86117C697E79A5F4F65FDC08E4904DAEDAB20067EAE2448FD4301849E456D085F392DD1316 +7ADF75CCFDB723E2904A9C0C976D6B84DDEF9D92B0E15FB246C3ECC2D0BF314CFB957757B3A3E8E5 +801F520644E4601D291DA0F7507C06F3B9BB36FC1C70EAA444E14E56C0CFF06C7F853DF36DA9D8B6 +AF2544B853DFFF535A7E5C6FC145250CDDA229956019659D0D253A19A7B51A4E538BDC01F74D7704 +9949C2C97C7EC6392C2E61CCC0992B66DAF1AB08551063E53180D2A67DE496716CCBAA45462D9F91 +B66A22545962DDAB120511FF08627131B95E5DEEB8B4DD9643E7B2AF65C0FDCE11F5F1E8DD468DA1 +8D41C8C4F00EA73836F4F70EC50FC3EC6D358C0658A4261C6D15A582A2C7C994E7882E661855B352 +014576858A265FFBC425160669CE159D07EDAC04D060B44E5800A7AAE8E339C29B929AA81D2F515C +46229D2080D5917AB20AB6B34FDCA8E4AF64ED660A3173786FB1A1D005D575C2A5187D3F7CFDC94C +CC44A38C5CD523E9DA726D8EFA6DA7B6131DFF3435FEE838B2C7D6B97934295F06202D307FF78D90 +6699CB9C5BBB10D1D4DEA5FDA5BFB094E704607083B646D37F5DA1FC7AD21B813F44D8C1AFEAB666 +55AAA19703BEA2E77DF3BF350E17C74B3447A452235919452B5175570A006C7680AC05E8950A62E1 +1D7E3ACA35A397D1E19630D094A86807593C97F4C484E4E06BCFF708B6DCA972E3A0009E1CAC0EA4 +141530F5C1B8AEF5E1B933F37FDDBC4BE22B74FE346D1A3F5FEC0818F8E61765568A2AC04713E828 +F98C449D9A1CCE52D10D61DD8BFD084C8D099A75D89DEA64D5A7CC68BD5B0593D97953DADA976383 +F5015915618AEC56D71D1DCD55B89736395C609B315A3F1E1255432FDBD37F38CC43C354FB4B7C44 +F1A7318B0B7E99C3C08C33B953727B6A6328051783A0A33E3CD9E498346A3CA6A77B517096EDD52A +E443B87643A646C3A7BB97F742888D33F9B3127E61942F4103C1DBDCD8EAC8F9E259773066736CA6 +53CE57E8822651261D847C131321BB9D6626A1AC50D047C0BA47B411DF2A995545BD68EC0287CC9B +31D5DDCA8755EBEB10ACCB3903AB0FD5788E984220443B8459E7C078DA4289F1350905881AD6DFDE +C47302B0ACB0D4AF8CAED02B4B70DF3CF8FEC118F0FC2D3DDE3E494CD160E676E300BC464BD4400D +B50EE43B314E0517037BF971ACD7CD327CB2134893B8A0410E68DDC518F5DEC966C7884CF5FDFE74 +723177F20DEDC039D879056CAAB4BF045062D3904F615C5CFE109AC7A35599C94024B41019B9AFD4 +04A80ACAA4837929F5C9317680A13D157A03B59A5588DF79D2E113F5F51021D6F6F90E8BBBA2C252 +FD10651BE80BAFD59C53A3367BA3C28DB6EB9DABF1EA99F47B503F627E15DCF3FD645FC52C5D5D0F +2F07DB4C25C0D1E1C00146E1C4D973E613CCDBD3F9450CC0F5343D79F05E9492E86A1BB889ADF405 +03BD7F3E7543436859184A5B20BD8A172F350D846B7570803990ADAA48D4B9155A2B4C4BFBEF1E1A +065C08E03928559735BDD442FF1E83E1FA20A5DA57D8BDB2FF5427C034CF0128AF111E6E73099E04 +6E0C240E80A73D7BE72B87834E45898D475521CA3306707631F5C6136199F354632D1A085F12A1C7 +C473868B62E534D15F5484323E63D0574196A19EF175214EB35A90873EFCFB92D6CF68761D45E37E +AA61E1A1979A82009507CA193E44B36A806486665CEDBCF387053ACEAB979BD35D30978FC7659ABB +E844F4ECAB3303318ECE80777A5FA5A9DD91B3D06804C4B4E9B4EFCF07EB89866D0DD8CA390CFD15 +98651417114D78776B1A1D36B4BA17746D6BE7FC123D473EF1EFED1C3BC1D555F914536869FD5B0C +35F9C83F65B0E6BF7A627B9202D787D72C600DDB6BCCE613D88492E13CA0AAAB196E8A49928C62CE +A4FFE2D0208EDA334ACF47F20BD793124D2C5546C03F4A364369A76A0425262F9D9118AF54E37D32 +E33AB25DD533A49DF5FBF1BAF4CEAC2D9D378CDCD13B00FDA432D9042F623DA41AFB80699B5538A2 +5403B0B3EABEC9E8EFCF42FEF3EA9F91766902CD206B0787C187D5370B60AD6DCD002DE2DE8DCDC0 +B4719A797C5E26BAA67665016DA0D967FA1346F9588AEDA174CA001B31213617FE19EA218EC23597 +79D979E2663166489C06993230B0D07973A117C4E3F4A4C93CF8428248DD5389414D679C69644142 +67C7FEA17E35B0CEE456667A9B1875C81B2302BDDEA2818D6019FC1622A82051F60584ABC904CD91 +8676305DC03FFBCC64FDDAC8D8AA9CE2EA00D6C97BC63C8A617DEDFC0E40775649438E9F61AFD179 +5E3B20560B01BE5E0983F136CF48AB206954E41DEE0D9DDD953DFD01CAEB569151D6BC0DFEF29D70 +FAE3E198E7EDD8922C0E0BCB8BCCF1C016142C1A8B337AFA7A05A9D7534B184BF3BF827F371E9BD1 +9A71244ECA1BA73D484CD2FAD54DB2F0EEFBD54B536EBCB5094E6BC2F5B2AAE41F05B4B311115876 +ED42C34F8E643B53372E3F6350DB8A38445822EA9A33E27FB0CC42CEDCD1FE2FDF723FC47C996EE3 +56C402112F24D0AF899B2D00BEA1CFD427998BD22B2A09046D6737814448ACFB10D387547D7009FB +384AF0562C85694C071584236D0F1F3D3FCD0CFB38B77C81889061E668BA7AB37AA60F58A3967DE2 +6F939B79CBF10A9DCC42852561D8D6754F1B660D216AAB1E133FBAA321C56E2584BE5C9BAE20CCF0 +0E8DBE6D9C2FCEBEBAD945C3C04101D2387351F132628786F6D9D4CAB83419288D31F9BC600D9664 +12E6AA457CE6CAD26A4C0671097B98C2384C81DD8B9A3222D4F4BBDA7017895C3EDC26662779AEE7 +40D9D7E24185FB821970B0A3A94041A69E4805EC88EE1EE521981536F2844FB8F5EF645F67D42CE5 +148E2DDE43AD5AEF200EDB3A2C7866C98458A92666E5F9E070178BCC39F65A893102A10564AF4E8C +AAA5075D2F8CD7FAB0401C03AF299EA3515CC93066744EB5AF7CF0ED06675BF049A6E3C211A89E16 +DE5BF0445A7CCA6EE8EB0347454950485D884606651E5887FE8B24323E2AA16DE22FC1FC8C4F06A8 +2A1FDE5758976024068197E1F4506E4D3D8A16D40461A4586338B374A592DC60334402F76388AD6A +457DC3F54E6169CF7AE3959676E966A45609621055EC3AF80E182633300A4418E34A66DDFA6B569E +5A13C9115B5FD3EC1CEBE50FBA247F60803AA83976F00117536342DC3D9890C49B2AC701D370E43A +955118967827760F7091469C5406F08F18D7E3548148CF0E312B1DC71DF67A5E7A1656CF2F47F3AF +F3DD50FFC2FCDAB7177285B29C17CA43019F62AC6FBA52D1493ED7C427526470ACC8389BAE827759 +4958908F517B2863B83292EB5AB3F57FFFB08393CA610FB1FE905D88A0A16AC395E2A2A6DD033D6A +0D68992F830B2E1B95FE357BF672716E88FFB92FFC3D62945D1EAD22BC68C51EE0E10A43011DB94C +44685A5C4576F6EF44CBFB45F2A4BF110A01657DB51FD499767E78058199B31DFD60813F1A344F86 +289F9378231D5B151C92385E3650B4FEB1DC91018EAB8474CBF69FDC1496A4D078D2C351C8196451 +247A9DCF8117E5B637371D8E22E248C64D999015C3FD2311E9950B8EE0922FBDD3D7BFF766BFE9E7 +CE0BE12F318FF2A7B5A9C6D00A54401609304ED2C55F5C1EAC3D4B38355BBD85D66D61636FA6E30C +2E82829376BEC979A6FEEE040E452359768ECF90CC539A546F17AE906C76F14F86FF697797322B05 +1EB311A759FE260C1EEE5DACF383816AAF1294CFFA7BF87A4D9BC595EE8F2C2F86FEEE11AD959D86 +F22FDAF4CEC098942A57E57813A0FA99239E994FFF353C1E781D666B8928CFC648FCF0869FC68468 +BDBDA7D280DFAB8B0B3A4CA35B074B686DE8D372C61FB32305169A1A9912F6541DA16CD6316A6EA4 +51524757BE5CF6E820011BE3859FB8B8578C100FF029680E05F0E0BF11D33FE19460C85EA5E4C0EF +28E29407C8AE6BE01CFA0D5022BF9FB01416FFF722A784DFC8FCE330EC95737A854471D334FDC58F +AB42867A7B62836A8B56466E9A6C1247D46EBAFFB905CD4321970F59FB8D6FF65FDDD34BF913AD32 +2E68455C5FF2D23C1A5EAE687F259BC982B6A384D35440F7C693CF50B9ECAC0B5578CAEE87588B56 +2EB6B7F42034C9F2E545EC866316552354EB3728C7D26527ED75174EAF635E048B08DC5D23E88981 +070AD5641A652F2344956E9CF4C16E652A99F4A644D1787D6D36537489DA4D74E61B2FC4DFDF1D1D +9D58F9C26C5EB63200526AFD168AC57D5611ADE4D4A382FC28BB60F9E7D626A6C67AFBCCD1183C5E +3CF2EF210D0BF5CFA7BB10FA3887BDD4CD96EEEAA8F9219AA2F10ABC0A960C3B57C0EC0313AE10CC +FF1F522124CFC8D2D49BFBB0C193EAFFC5B48FB3FF30B21CB76F0A4C0F1377C9223145BB0468A5D7 +1B9BC25873EA12E1C60334571C67385C00D0B570D3FFC6C7FF0DE62C183C76AEEB12DFFEE1459E0F +C818C621B8D12FA1357E2B55D48935D70BF140B4CFFE8813DEFD479350B20DC2EB1D3CBB1A2D3DC6 +EE975D58C89D61FC50E6A0197DA9A586B72255023DE47DABEFB11E8AA02414C2FF6258A281219B9D +DDFE41BA7D7977D0D6F18224FE22F7D4E9355FDB35BF7ED3418F4F68D093AC48F7D8FE4194FEB6C8 +0B9DC1F74E023C604DEA27089F98C3973FF9F4AD7BF7BAE601DB89B08D5D8139B95EDCF6C885FFA8 +B3E4B0477E7040225733826BACFD1EC4A0DD72DC41734856AB9FB700DF83CA2CE812913BD142D84C +5C83C0B2583768198AF9E885F2BA74877A414233207234AA5F18840557CA11682AABDE8993533887 +7C6D404BDE4153C9827EB16D66C1D73A8143C8A2D3604FF72CE579FAA3C5224BAC48EA83BA848429 +9472007DE96466B5B29ACC7C03B05DCAA38A48BFF9F214DE43146AE4E04FA705421917F99BC54533 +F0EBC01849E396216B9F0794E6F6C6B61B52EF1B1950C0FB609895C3C55FF574163FC8B6B09E66AB +AED1810E698FF37CC1F926B2CDA3B48C7D77790EBD2D514B6F385D397F713EC3AD3954EA9C846158 +6031D369E8B99E53408A79D64C34EB5A56DE8A67DE91837960E98A66FC04DFA0EBDE21DB003234BB +78665B039D0A469A0221BD541AF7149A2A659C300132C14581EF766FFFBECBA8B58A5EB3F95446DE +F49AF863A8113D17B2E7E6ECDEAFC3834D4DF900E3475596E86FBB4E2974C090DB4AD61A737D611D +92B4535AC291C56AD8B1C031D2F9B505BB77517B737D70AB3723DB52AE2ACCD5DD2F617423ED3CC3 +9CA882EF41757BF7151806A9B8B0F312808863E3673FB54DE939B35CDECA7FBC4DC3BDF5A5F47D35 +E345916C39366C8B4F439CE1C6F1835C320BD1E67375B03B5DE18C93256F251761A4C8CEC01019C0 +68E34447BCC503B9571FE8000627A6B3DAD5854CBC0A2D69E5A8F46BC78F6A7B1422334EC7A98ABE +FE9B83E01DCF3C6C9273B346F3240EA225AE4A4083CC7B0EA141A0773FDE940768358EB4B13D82AA +304A1386D450C1C0C6A7D5A8FD2BD313F78F85248B5196241E31E5595F3BC01F37700A2DD3D4A0EE +2DD01A36569CD507130E8F5B1E96CB560BB7DA15560CCADF3B2C9804A11D9E8055C9EC70E48C1D21 +3EB756A1376F2EDCB7189D78CD3D6CA5865537EEC31C17D801605EFD860B0B629472690588D02575 +02C6F7A75B9A1C1B397781329832CF3EC43C09F1559CD562C48FA9500295CD3B0A790DD3FCD4684A +7C7AC49AC9BFFF36B39A9FB148BC28D37907433943CBBF0CBDAB46D3EA86DC8F81C859C52D15302B +94A9B51C199B7104DEEC9D769C2634CECF8B700CE9C04152CC59C9326BDACBEC4312DEED92DD087A +1C4840868D9F97CAC046581F762F75E8D24D6445370A3F1E0AE74A6478D9DAC37E7FA5BEBEC0A1E0 +81AF89C1BBF7F51E3E2E22C8C405E8671BA85F1BF0DF79A465DAC7EC07F731E00632E017D190A99D +83E27E5C2E63D7DABBA23B2E88334C63721AC5A4CBC5D45F4C177259F34C2EADE01FA008AF65EBC6 +01D8DD16436D86AA94C99F3CC0A2F87134E73BF22F108B825A8963B49C6C685474AFE4A542C8641D +C0375D7EFE9AC1168D9700459BE52D0DA399023E141969F25C0DAC4668534B6647EC85454BE945E8 +26B26DE6E3C4584B97A38E2B40A0D23481BCA78084FE80E00A71A790BF31DF468A435ECC88E60A57 +860BBCA3D65930186E9917CBD209C230E8F8255A7ABC7D3F043AE4D7AD63D9980BEDF062B7D5C298 +C40225B6D03F29A0339E0FCA02138E526F06B9EF47F5E7A8068A846CFDE2BFDEBD24F5A73A66C079 +18662AEC80B43246284FA4E2EE0D9AAB172B1E59A6CC46B801149D8C0DF6DEC9A55D8E1B0EFD9D30 +2FF618075944CCCB6831D336B11617107B0530D09885E5CA11A5F1FCC8D69D603DA16BEA51116D42 +CAB1AA1E4D7B9B4D79993F2BFE53EAC904FEB70B2D330A89780EAC10D12CC0C35B8399F218AC2976 +E57A26BAD20CE2FA2AE2363D3FD2A8A971747556F2959DA74A8963C20B504711AE1CB0D0C02457FF +2E9BF696B159AF031DD5155F21C0F5549B0471A3C5DC8918B675CEBCB23E29322B959ABC05283A70 +2E878DE8EF25EA760F3C5C7B7B49D398283DE2ED837FD59F7C22D62C58FE4448B1049FDEBFC8787E +67D7DAFE9774979BB3802254DA59BCC0219F98C219F84D995CA768B8B5D9D4A32525DFECE003675E +E4BD5D8DFFC11025AF2B468F9207B5B2B42349B98232BAC0759758C1F4A283405815BD7145C93FA0 +8F3ED2826655053A3C2559073D8ACD199DEA2C5BA5F616A2E48548B4370EC73493BA07E197165DCA +774438B0766867819C1154D1959FE6E01E6312E0AB91FC2E2BD240FC8652A2D456A1DE7F34EF372A +53794D4C4E050BF3CA5B7BD2F1B8DE93B4C8002485CB219AD2D029739FD3C81CC6E78EDF38723576 +1A57143EEDE5CC887F282FECD261F6A25D0A7E154ECDF5DC38E426811BE86AAA458577E5E0C5F0F7 +5AAFA9C41E5D1DC9D91ECD79B514F8CDF7A5F1A189470D35FDF4F9B8788879CCBD91B427822ED658 +389E981E0EE5F7FB87692A3E3E931DF8A1D1573E3B0166204240B7080089A09EF7487C9AEE2D665F +5A82F94C877FB5B0DC531CEBF1E71C6592CEA2401E4B5122E5091DF03D203DF979B9A6EFBA12E2F6 +B422FDF15D49AC0914D372D21E871DE65CBECD105FD4A3E4714B9CCA5C6803FA39DBB015EA8A88BE +7913502E562E5B170B87BFC8572DC9DF49AD63694311EF1334444BDF0B4CA3245271C1F7A4D7FAF1 +703E3AA0E1EA8D5C6E821B28707EE0C9B4F22F23796FE87356C58AE2CADC191F4C58E1FB58DA03B4 +5A25AC95DBAE13A293474217BDB214742B9D9D6AF35F70FED2891942EACE3E625E55FFB820543FBB +250A062D3D395BC0F219ECFE0D76686AC148BC41476A887BC494DDBD396BE200FD3E03CFA12EC9AF +6B934A283C42AA05589AA6B4A8D16946BB51F50419CABECEAEC5AEF9085C9989289E9B46BAFB6FB2 +782D84DE2B068F91A9744AAB237CEB1BA513E57E4C307108E993C972A3E0A898D5A8D27833155031 +FDB98863C3BE7FEF3004CBAA5CB60A1F2E3EB4D7290FF5FAFA088B1CECCB6CF51A58DAAD998F0839 +6CDFD68F5ABC9C1CCB8F6514107773C69C26873E889D1F79D10E866910E4684186FCD71C965ADF62 +39BA3418B313A27AD632300969B6F284519366ED85E7CD968D64823F8C59B5911A72D0A20EB72B60 +3A61E36F52F256FFCDF706B4560B4DFA5D918FBC530D83A4B3C01BDD3CB4572E24242D141BF9E775 +36693A0407D002E09CDA5B195BF1CCF430AE9824C07928A050D0B460F2704BE8F9E647A4884C4567 +0A81EACF7CC038643EB0FF18A376FF6F32B6FE4F197273327FBBDEC6443A299CAD4B26F7778A99F6 +5A11BDE047153E764039EDB251936AA43DEE50DDFDF8856519056AAFC4C5AE6F2051AF0579A9ACD4 +1D00775D7DBE70022CC263DCA5E0A25B9C7C4F5C418587666B2FE24816B1E0EC92F9074F1403BB83 +AFC3F1D52CA79C387BDEF864366E34C90BE52F7AA09935373A07E4E026224E76F9EC3CB9E7EDE50D +EFDA48248D61F3CEC880A3B8843306375D9711E58645F3625BDB8E87052DA67F9794EF4AF8DB0BCF +E00677C3A26907DC651BC838C40EC39E2B5A5DC0DBD345944A6C32226089D63C52490FA10B215AE7 +03CFB663EB8A47793B84CE7364DA1C4E7FCE32DFEF09490121222774915BA59C78C2275F829D15CF +4D8686B095C38C731B83D48738C25F40B8ADD487C350A2EBE846C3916AE384CB1050F9F5DFE09FCB +D9129C6270FD86D55A459618FDFA4F907E6B4746196BB717865AB378414029017551161A52E9D24B +E4F7EED553A927933D4ABC8F25DF607779A717909CB4D810DE8F5762581900E224E4B91598149BA4 +71CF8068ABE8744356B261600BFCC57FB8BE45036CF6571D9B2A95304933BD4F17215F8EF53F8E08 +1AF61FA7F9583C34EB5655CB0ECB82246959F09091F36989EBDD646BEDCA614B9A61AB7696B3FF18 +1058A150FA6EC1BE2EBC7F64357A3FF2A2B0491D2F4E0B970DE5B7788B467CA678039B5EF55C88A3 +84578D427FD2CB16C87B0BF0A3D37CE8ED43E0F049AF2436344D5F47C948C632C94A287509282561 +6C64C5D262FE5B24916FFEE982A69A6CCF888BD01D62EA591EEC51F4B7DDFAFFBEEA93FE08D736C2 +0129E345D06B10246A5F57151C198D407730713F32299638EFBDC01367E23EB59AAD42A83AB41B43 +2DB462652E29813740F4680A5D4BD47B18328FAE6BDF4200CFA4CE3773809B45E8887C9B2E423698 +9F6C48D64F5986F563D9A7538A8716082F81936AEBD0461E6F4BD470436D8B7656F0FDF89108E6DD +02ABDEF907731D458D690BC608EA9CED09EB1E6E64C0790C7A2378201CE997FFE0317679EE1D4EE9 +F91157449323E53B4ADA8096CD628B5861BF794543A98F2FA2AB54FF0F25A13DAD43DAF9394329B9 +5AA53CA32749FECB0B2BC035DD1EBD53FF9FB5AD8BCE06CD89E5568091C1CC314CFB1D9821D7F9AC +7C55F55E0A16E39A87D43148201B928F3C42B110FC056189DEF183745F3B637441DE8BD4C3C7EF12 +F4258E306B2877ADAEC63441010750DB4E6269A4C78A0AC01BB3603C386651FE814031CB5D8C1F14 +9EEAFF652A53E57BBD4C8C0CE36A84A319A53BC1E5FD3F1ED1EE72F4C1A9BF264B594062FCAFB22C +C1FDE3F2E3D3C17DD3F7FE0E15EBD812D550227C06D01127385374A11438ABD50048E17255FCD2BB +85122A6FB9B7DA9D5E9DE8A747FAE0DA45A1FCEFE92B9E70A5B2CAC668D4D07527A5C1403267D823 +048BE671F725CFC7474B44FC5AAA348420B2D7C23C6CA066666FD6F2208E329878D90CEF1C2E77ED +22D3BEBB9D547810B189F08920A27E7107F208591A84D463CE2576C70C3DFE6643E4EA93F4E1DAEB +41D46F0E2F56FC10C69AD5034FC9859D31CF27A3A1EE256C93111F81C11ACF1FC0CE20B90BAC9AA3 +27A5C85A7985B951519FD4B03C40BE637162AF41B2FDA68F0D1E9B7602FE2659D3D75955C579AC51 +DF6A552EB9581AC3F712F083F19B52A6C4F560F36C59CEEB0C996AAF1728A2AA45DCAD79BD7B23AB +388D5B0B64A2B95154B6259B730B0F4A72C8C7F7CC93C7D64D9D8810D1F63FF8ABD4DB89824E2D26 +4FDEE916C41E299211DB1A53256E1DB5CDD04862F034D9404B73183A99D3D13D642A663F129B6D16 +7095BEB4EAEFD03DF2FF2F0B6B594C1EE90FDB203DA89FACEE23F1BA3901FECC75FE1811BD701259 +343011262B6A0A9707AAA6316BC3C17F787BB80AC8DA5AAC942D90F80C5A3BB59E47EC767244AA95 +C63E50BF809998957936D3BF6ABC24B0A397258F9EB4DC8F65692CB023D9091FB180C69498CD0C08 +BBEBADC84A7E0016E8F8BEA325D924EB0DF82E75D2CC2CCBF039B11934363D4332C5FBC5EC556BE8 +5EE4E707CC2753CCC43D2ED50558E51A104221C9323CDCB0199B7B83454DE3FDC810D0F362C0299F +5DD981B31D8E3DDA284FEF9DC8F9C8DE138D3065437A7FE8C30572AD06D62E8527AD37AE39AAB0B2 +25F76A25F6C6505241ED73BA494CF923E919F688DDEBF193E188F8C4C154F21631080763B4D091E8 +AD1D2FD6649E0CD9360E8D1A67A5B5FAFC67547CA31C95A5EA8D4EB5D68B9F6D6532DB9B54584735 +9558542A2AE58C09F3BD2918EFBE1699E9C8F2C2A11EA4D224C726D2ACD4A8D8ABAEDC6588CF2AE5 +66528B94F55B823A2A1F7BE19000F3E7579D094E047075DF18C8C868760295533B26EB3ED90635B1 +29C17ACA679C3E88B06998CE5A7A2544B700229F5A6A504BD3E45B276471959C8A3F81917A534287 +39B5EF9E3D463B3BA7318448E2A3E79520D2D245A2A72F31FF7070B6E4624E3A5E216BD103640C8D +F387E49D732529C611F8B971073F17EBD2F6EB18F9B74A67E1997926DF178D4C9EDED435B9682F1A +279C81BB9F60DAFE125845A2FF3B02979E5481C78A45C479BEFB9FEF3CE2BA9BC46C77B50B03E48D +A6D17B76F06F3AD118371ADC69E178C52B5FB4B261C9311874ED07DD6D5B3226A005FDD7A6D53848 +09E7063F036CDEA41619122635E835D2D74CBB6AA9B38CAA4D819C26E95115FE0DBAB4198FC5838F +2C91B7A87B07D734C6D4F4F83444C1E90AA9BFC908A2BAC4B3DEF9157AFCA5248F2DA31CA87BD363 +AC25E9E77F741D4B2C6E02F04987A6F49D30E9038CEFC41BA172DD675AED8B392164411144E5B738 +F3210B0E66B17A13CB9631C33D44484E792A7C082DD0A5382F34C5637653261B1EB6D2035B08B4D9 +1FA9AB770CAF40A103629511F7B43F2743D7E583433DECFB19C21FD4FD0AFCC22A4119E77C87BFE6 +FE50068B22479015BE5A9F06BEAB4D37412E062A45E0CBCD7BB39FEE747E96306F79FC4F2E8942DF +5D9DA0E55AACCDA547DA19D30B8404FA121298B44C9CCE198C708C69A8D6BF17591C5C50D3FC5BE6 +961F7ABA8F366DAE957A1C3730DA4A5B4F035A9274675EE3BBF0CA8CE9D8349F50CABB1C3EA4948A +BE6F9F143592F1EA95404E6909A909168E3279A957AE1924245C356331A75E7008BEE92BEAA304BA +40B7C3F48F74D9018B3247DF50EBD7CE541DA48ECCB1B0BE51A455C3C13C279D4D8676078C3EBE43 +08748D52C9B041D3E7244C745B1F2F742D010A9E60695F3EC4FDC1050AC082B905D6A57E8F407A3B +472F731011A5798965B7B1A307E252FE02C8F79CEEDDEB6E165F1A94D7FFF18DDBDF79477F14E9E9 +3981ABD200FE7771B29D1D2D120EE79D28B9543818527039AC74085EAFF241B56D08220C958B5D9C +87C0C04A14D52AFD475B542D391BC54FF33DEF8D9484AFF6873BEED32DDA4B371112B523B6CE22B4 +0D1B416B64C9370F1CDF2C548F4CCBE9E12E21C36CC3EA52DA232DCFB65F66B22B5E2EC04852510D +5E264EE939BB67AEC4764B87062AEB7F680B40BCEE04AD45C7519EB3B6199C9E0E332661463647F2 +FB7EDF303EFEF84891CEBCF0FAC5F723A9D0476C3F8C092604C87FC69C7A90F4D64AE45A478EE8BA +2DF50FB93F55A3546123F0B0E2C1C40C98EAAE9F0F26B8F80FFE6E6B94B7E27D2884D58B8A119662 +2DF6BE608C5569D7864BB756DF2EDD184B90812B44ED4A32D001C31383A40AEEE9743651F7950846 +15C48E402DBC01C818D477EAC0347795CB2792E9C11E8FD4A02E194EED1C919D4598FEC003B6D9A8 +A0BC7D456047A1C0579453FC1D7CB2D158D466939A23D7A7B8ABED7E2777EC7487973E73F2266D9C +250CE30729E3C5223AD93B9AE8443B35711E446A3DC660123ED45CE1942A1A2AD0610467E081CE2C +8B92A6C82F0B17B5D2429E99F1A6268072C6B5AAAA6EB6283A872C54D3694CD825EB2926E57DBBC7 +C1663075E687A144E4D61C225781D80FCAE1497B442342B4A3F1CD6BDB50E31791CC3928C30835FE +F845B6BE5E2D7E3F2F5F085AA3FAEB45CAD0D76BCBB1ED859A9CEBB9F7457036F0BC3F195CB1A98C +9C8648F6583CDBB23894BC719D68C2DBD8003B10D08C8CAA40BCE784D7BFB4EEC9EA5359AC056E57 +B8B0F2EBCB1F4CE40C87FC7861180133E0CB6CE2FC4FE690756D327A2B5AE063E3021C0C0BD420D0 +56F0B941E6B36088A55BA11D0C35FD0132D5F48E5D9673572347171B4328D4807B972831C0D74CFF +A5638C145B89C989E6EC942148207D6DB82257585958034D9F9D4221C7C9F7013790DBD130F277E0 +BC88BB179DD09E27062379ED06F25EEA8B7FB33C35861A0034776E3813D2E9E5C10E227CC569AB36 +CB2D9DF2E7B7B44758F9DC4FFAD7A24AC7E9F47AA850C221048C3CB35A37CE8EA75632AE65FE3212 +175146FECD6334AE3D3C5F492F067F795E1E8FF386BA198CB74F0BB4DC0000DA383BC4CC3F070DE1 +7721431988D69C8B1A5AFDCCC83C22E16A87E01C6D3E79DC7AFA3DB0371B0866EFB8B6F88900472A +FEF1C4A878243C52D4E02E82658979731C841C489A6B97E271C4C93800EC7D91F93EB9B9C659A554 +E1FCE42A5EC65AC39190EF4B66DEAF6FC0569A000A9E1495F42F706FBEA4D32EB7EF11A648910259 +6A65CF899C2F322F5679C6D123469192A9BF1A7F1F2C81C554ADB97BD19ADB746A4F81A4D5559E60 +AB94C483DBABF6CE2F28CDB412D50FF3FCFA3B3DAAACC6A83CFED910CCB3B8D2C19590AFF4D75303 +4A6CE7F4156896A13808E0DFEAC547E69D3C886691728E4A35ACD575B40D721E8FCC5385A2EB28D7 +08101DC50811529528F5CB0C009BA7E3C88468E37768FB0D83895AB54DB2DD5426562AF9D8AF304B +F6EDA54E9C92643DF926F5C3578269750120302A37CB140A18BA56BA01108D4ACACE8FEAE640A6C6 +958EF156B588ADB0EA5F3B0F37BBA12B7BCB221C811415387B024B7076FA4403A3AD6EBB5D9C26EF +EBDB7ADE7C60B444AB9F90EA493B658B7767AE2BE649BDBB3FE85F460F1ED137C61BD95F7CD3D8B0 +15CE45138538930AB62AA0E54B4CE1A5EC5FEC0A2B28B345B67089A4E4AE14D2E1F5A9C8848DA688 +CA298F93860649EC3AAFEF3E820D86988C8E3E5A4D4BB937791827994AA3E81D0BB3EE115EC36D5F +B9A392D09E79AF514D11C7B3A03C9F9C13355CE79E119A19177FFDCA34704D38118A8976D1EE5AA0 +2D14FEB1414419F5E85244ADC5C0A765A522EEF36170064BB19FEE3B5F7B441E4DB967DAE0BAC2C4 +8FC6A836E0EF5A69F073BEE1699F55E9C757EBD6FD8B514E2B49D6333815B7DBD1E0694695FCA3D2 +1320A0C4B852D9706DADD8369A95FDD917328BE93DD33818954DBD2C212D2CA81560ED5BC284EB04 +7A5F389E24E43F4FA8C97FECF46589FA7341076555CF55B1C21B28E0C1CBB00AB8B6F67472F27BC0 +D11148F407824B0159B5188D4BB7386FBDBF1C0FAF34721B7BCB5C0FCB7C4010DCB6A1284E9D7883 +9E3C2111A05D29AB7997073B590A81C6168020F1D48951BC7D8476D5BA593F4F23CAC1F9BB0E091E +84B4E99E5C584D1370DD12DEE8DF16AF8BC6B7B23E2FEABDB7F32779AF8E2B5094A6E9B7A7225F24 +C43A8E5D2B977E1E19E633C26771E23017ED233DBB02C64F8CF03992C6484528D0C8464B46F24F9E +8380F385D5D01B8893C67FC103498983CF939432AA380CA576D09030CD52FD99BDC3BE16C7204CDC +3365BF76294A83A1FC14A236F5FE5321904E779B13232A76F8FE521F425562678436359C2461BEA5 +AB27209541F557AE2AA60009C9CA0A9FC7898C14306CE35A50017BADEFDECBBF94EE2905220706DC +806409EF87DB1D73EAB0698AD2DB72CDCDB293E7FB13C94D9FC87E74502E6927A212F0D7D2F2D194 +64F7A66AC07872E18CB1DDE8F11835DCBC5C4EF039333FFFC0FC1456DAADE7DAE3EC2EE0D3415B0C +ABB69FC5006F4D14A4EE1A5CA99AD4D5E629C0DD1E0F097B5B93DE2DD001A8C418234C9C45E8C13D +1AE04E9466DAB8CF1ECB88A4E059C111A6468D2DABB90DA79C7C79E94DB28F6968B1A632F8C57D9E +565FF91C6916026FFAC0661856B9FB8DE9C81661816221B1FC159CFEF1751E7E403F5F2CE32529DD +540792FC17A12A3DCD7C50D38EEAADBD10ADBF5D8A82442AA900CE6150EB7A4639DD9FB6E385B2FD +093493DCCD9014B23EB172E21AA89643A6CAD1093343D85D81261972DE0ACB16A4C6B5F0BE4C978B +FA12D3CAF0134F9EA49F6E9687C8F99A456745EA252F0BA9968C7F9586E3DD841AA92DC7705BDD68 +2DAE41518A09DF0E209F321D7FA3417202F4BA76A984DA3ADDBC58136885362F02F0A24EBC439B3D +BBDACFFD8498EBD29F88F016B1FEABC10785438EAC860B554525F3266097A675299AA0967BD3B7A0 +EEEE3FC578D1BE99D3533BD91571AED904BFC9DA1A1451FDC5406E1CD614E0C7FBC733563CD6CE6C +C31E9237CA153F1F0411114361D731636BCF98555ABF12848AD109371A42B63675A4130B81E97C2A +2EE2BB5D8FAE2640156001AF0F55D9D5DF8FF23C8AEFE14F120000F14149A36E5C94CD9081DEC277 +C2C34870D05011F99D48B0875A5FF542F067F7E9880109F586BCF2B50522A1F23ECE44349E539E70 +F84E207DC9BEC7CDF856A046F1A03226AA41F541719AD1AF88FF211E57DD0C1275DD0B7B47440DA0 +89B98C6EE92A7D94700B83CEBE19EAEDD8A615F6587587BA8BBA3CE3AA5E8EAFB1FB0F486BE3609B +169EFB178A4292F4C0378AFE5D24EED1CAAB514DDC66C696D8E37F294A6579131DDF5488E9436609 +ACD750C3DB0A940C84FE022B22ADC2676F62E91E8F891225F891FBA537679B24547BBBF35F04915D +20B11739F620D18B5B216921D222F15044368569AA302980B9225BB839F494588481B94B0C724352 +B2DF600A22B062561D86CB8F81514FBDAA4F8A043A0265F992FAB71FC9124A45B8475E1EF3DF6B6D +E35CF329777D45F08325E8505EC0D979F542807AE77E57E453525F23BC59A50740371EFA98678AEE +6C425374AEB745B99DDB5D8D908FDB551FBC0DB15832107BBECC4E11A1A8DEC69358A574A2ED46CC +31D564549EFF23102D92BFDCBB2BB985F78F36033E34F59C0EBAFA3BDD71338736464CEFDBA91398 +33995EDA4207BFD4A9867D32E867FBEB7DE60D132803EF9347CB17BD91315484EF6570892297DD8B +7D966103339535E28A00CB1EECA4A9775F60A9F5FC9BD8B06D78FE8E6318C31DA2E847E3F9CA587C +B01AE2BA0A2EBDE308314413F4F230A758184ED60D4F71F6CEC22A93A01B6C54E0449A3860FCA895 +4A347B7588329A80974ECBECDA1070FBC055666375229F13DD995E99265DF870BC8B8CC6347FADBC +1A6AF64599271A475B9123493D46BEC41289BEEB67EB97A8DED7A9C9730D37C65164CFBDC22E5CA5 +89D2E7954C7136EF4E084C43A6C7F361A3E96989239BDDB9A593CC2A80BA16DE9EE90E95CD39393C +212AB22EECB677FD36D34DEB46C4AD0D21BF7E6D7CBD0C8083842FCD87B18FEA7CECF939987E99BA +34C214E44DD84C176C9CC5A4CEA76D380CB316BB4EF9DE73D73B4AFD4ADB54451591DEF86621D138 +D5A0A29441502BF6C2ADE671CEC3CB5CAB903A657EB2D70C943F976C110E46C5D9D29BC00A875F27 +38E5D22496A43E096E009C5D3CB724B4CABB32838DBE527F83B18CB457E57B092C302EE557FD4F00 +DB9C56E66C9FDF4EC9FFAAB85F60D02BA79694FABA476A199A0331C30A78A92E10417BA236E23364 +8174C826331DC1BAB87C5F95027846130C6A2B4027930EBF9A97BA1B039D386FC51C302648E25980 +212F6A582CDE2778C677A01FBFB3C5D1B8A374ADAF6ADBF7DC94075F25ED66D440B3922C5F255FB2 +3FD8F6E21EA65B1D93BB225684B50F11310E242B087575973345B229BA62C1E2C35BDAEC04D10148 +F5B2F3BCF7399BDFDF1F3F79119714AEA697245BC647316EA157484ECB951BE367234FD02E8B1F09 +1AAC3D29BF282DFF4011BC0CBA8E55234D943DB3017CC7A766720BBC29B2D097A956C0F1067177F0 +12D42ADCB473CDE8D1BA35B4030757FA1D8211989DF3BD22CE5D501C21EF8708FB3449DF47D88650 +9FF7B59B76C0DBAE443F336FEE2D615D7EED1C284F14335BC8A26BF4621E10DE9611FB2F1DBD52E4 +B7565D8C65B54EA36D508BCF0C578A49A2665227CDE1F9768EFE847F9D94F1BBB7DB83701C232198 +5C7283D47B2E40B27A268428AAEFE75F6B2F8764A8494E5827573758CB9CA46FA93208836BCCC8B5 +564A69F5AD882052AF1C1417C3FA7F580569528682C77080F3688B65E7FC24D2A3AEB61574B4A321 +5927281544DDD7A6EE0A3E9388F8F631CE7251724DF70726E5912DDCCC8C652DD6C9608F8462303D +867F589DE0F2F71711B35142EE6EF93B64D6326C4DD7DC83278E057100EE772082E6BA368ED91A55 +53ECFE2293A481E42F83BC8F9148C70EACE91F7B7D9CB8A72415BDB3AF66F68EA733A17ABE9DB005 +3BF148629132969589F38D30EABFA96A01FAC72650B5A6FF3935670198A1EA33810A9B11E330EB8B +451F24F93544263436F669AB5A90A53B16CCEEAC36B1445574EFA7E802DE73522BE725E68704822C +B7D3912717333367895BBFBE06966A5CC653AAB5E9B3596702086BF0010085B900711932A95ACF15 +CA4DC45A754EA334E9EB84D6FC8E3FC4F897456BED64BB93B593549FF0D5352275D8E417172A6664 +C5E0ECED1019494A7ED49AB0B965BEC1A82E5873766BB38D7D856049CCE2FCA65AAF61E961B60634 +E2A69EF059754C9D8163D87F928C222772D070D83FEC6FA5AC734AF65E40BFDE521F7D9CB1650FDF +64754BFF21EA3FF0AF7611A93D525EC9B28C51AFECB04E7FC8323DD6C9B0D8539A34FC3CD8CEB795 +8E8EBBFED4313C77ED469C199552A9FF70BA5423B03B6148D4EAAE17B71C5B39DC436AC53D6BA8A7 +AD81AA8B02335A8B2B11E9F4FA913159A725B8AB60F52F1A2EA50EAF4D56656E615BF382CC68A690 +BF83DFF24FE986570ADC0290ED1A37C1C2AD469CE789E0EA0BB5CE01020100E729721AF3B5BADD33 +A2DAA6C33EB8F9064F5292F715F820B4BBFDD56F76D42E7A1A068C1CBDCE4640082F6E7D582D1939 +990CE6EE8D270015A2C461798B37DCB5798EE9F7512168B76D26C28BE4A49A1BF96C89D235F21A1D +B6A96E5DA474D0B19B808D13D7A11BF39EA8647499C410ED9894A1ADF33D41B6FC2E614D8087F4C8 +4E437B136F3CB32DB8393C49177A0675A0C9E7EECEF448A97AFDBE840FA01FC7E5F2E8FECEDC1884 +84C312E8635CD79195475DDBFDD4D38D5A0246DE2C7F21608F8D2C0DA1371D302E941572E5792A3C +F4E51A33228B93A814D03FD4FC223C314CF3714BB3A34BD4F7ED6348577FEED9DEB082C4049E57B5 +D3CDB7F26629E9F3BA36893E09E3C7463D02A22D7056BE76B87763260E46E48BB832B7EE13F8DC05 +37EC8E81E9BDFEAD8C27EBDF1AD706933EFD11131E12814F236EBB01BE85B7F1B2D627413B324918 +D247604F56EC128909873FEC3857028BEF76A3494364C2A7002D104D486236C30B48E2B75D851C34 +EA50BA7FFEB4E19190898AE21768C157C0CAC628A2181A32796FBC1A7271D2473CD88E5395DDBDB1 +FC3AA8DF0F3D588637F19A8B833AFDEB5F655A8838EECD684E2315B72C75CEEFBCEF94344ACE8D6A +DBE355008EC72FE7CEEAB01363A895F4E73F867639BE0A0BE67333848816B05B419221BE8F9066C3 +62C23FE85B7F392930BFE4C12B9526FF2FDEC38F23A159ED61A0718E7115C24597D849FA76369153 +54A40C965D4D72EC94DA61A03766AB39AAB684E134FD1407A5B1B19BFEBA52AA0DA5D99CBE5C82DB +AA663711E6DEBA180E1D4A39C320516A4350D296BC19BF1BE054859A0889C7E9727A021F3176FE62 +0FB0C837E4141FECE531A950C03D319E3255703220B7185BD20FE5DBA673F8129AB211EFCF36EE39 +4C7E00EB0876624BC840FA86E58B2F584754CB6BFDFD76810E300741EBE4544E5AC17413ADEB21C6 +2F66CA4F075C32381796BA709782DE34A675B717A2C7F6D88104CB924FDE5DF775B4F0B68E0E2E5C +2F788BBDEAF06D8E1FC2105CCBBD5827C0B03FD6CD64F0D073F3192D5F94839644E5EC6C5185BADC +F04112A65F49A8C83174A9AE958E76A2F5AF469E8B76C833782C5FFB8BD7B1BBBB3EA0CB7C9786C3 +BE2ADE5E7AFA8C8F20892659A59BC421E28845A108E34EE17864042EF587A6D67DECDFB3F510EB40 +D2229585347A0035670FCC76C2837A4E4D68304FE113C539B35C1F0234B5079B8E32934546982978 +C5E4DF955A454EA263C3CA5D7101F31A318D82A3F9FCB5A8AFD7A65209663B0FC9DA400B26F285EF +46D0E1EAF8ACB1F1CB805E3986D04BC585073FC64895E4DAE1CCB749BB439CB32EA91176D5C39C36 +50D10AFB9C9884D5FB90183424CEE67EF2175D01D2478D67511EC9F54F88763C152697B06D948BED +49240096EEE3D06AB4575E8E8B2CB8263B5BCF4FA1608720F52B675309833071879DF52C3EC2871D +20F398B5CAC8F8A4D41D0F1D47584DD90DCDAEA4A1CF160C4B3BF1AAB890B5CEB6CB3488672AA68F +BD938281DBC1D8BCFE92FBF514DA5358443CB6E0147254E91B38CE6787B2BB0DEDD2D38F5938737A +977B5EA42892520C58F8FBB53C994B57382379E9490F0D6970B980E1BDF8CF9F4C3C5E0A18F66E86 +EE93FFE7FE546DE50F41364BCB3721B637072571FA1779F1D672FAD260C16D7F13CBDF3E4376E7FF +56D2A710AC5AC35FCBDBCE2C9C17E523BBE6218617B13C1FA6679B308979AE7C61DA6E68369324C6 +CBC7DDEC364E5A86707266C0B459EE7B2C03FE584E529BFFDCE98C90A2F3D9305AA74D3ED8430DBF +3A49FE2ECFD9C4BC9FEFD22618FE9C8A973AD072AB6F713E4DF02DCDA7AC5359B2D652013E131B76 +B3ED6C75FD53BA58D862846264627F6B9E70D8800F6D9B32242B747A67BB2B45675840D34F852AA8 +062FA6B01E31ED24DAE02F6CF788A17F7B9368175195DB0072259CCE0FFB2C1035C1D26E1777CCA3 +D56A827C3242069E76D6DD69B653768614B9ACFF16567FEA61508D51454BC02F6C60F755AEF6AFAE +3536BBFA1823F8E1A53C41124DE983E51CEC92AEF4F99785D554488A51C20885346D1F761DA79017 +940A0C557D93F1DB6B3D00FFD61D08E96FF3AFCE5FEDF545CC9F47A2B1BB26713431D6D1E47FD6BD +6E3C668B0368241F0EBB5FA9C991DF79890E52E83A3675EE699B61BAF869DE91F67278F510061C6F +E41DE2D883F48CD0E068E2A652B244128D82E5CD52F35F210DDAE3054691ED55A7D99088AAE8FB04 +F525C2084AC09F5EDF80A4EFAFE981F74C0DE9D194320709B3464F3FF2C0F6AAEA6D973D9C323F53 +DE3D741F698FBF01036716BBD62957CB32CD81D3A2674560FFBC5BDC5C6E4F547E589AD0B1CFE14F +5E17FED1C4A8ABE4E67CCF8A49F32C4C6044F1431E1CC382E7758722A6D0DF9ED23E51F8AD14D11D +7B6428E27443715EBA4E9C05D6F238378F9498AEF0E7EE4FE6856622CC8E6ED141EE5F109E343CB6 +695C4BE1E0F66601C27975983BF557C04ACFC19227A1AD7E6C44C00529FC7EDD7F886D24B7E029B9 +C395260088BBFB96972199A7B32796D27257DE83A7402291C14FECDF7998C5C96B1EDADE0280F856 +8A8F5007852EED303969180B3329917973C2D32C080C9765B6BAB0673BC7ECFDBBFBEA980C263843 +39B7F1052591D91667D4FEE413AFC23DE2D4B9DA742F4269C6C939F5FC32A38040730A018155AD73 +3F231E4D5B9D01C03A58EAE7B5F590CCFAF25EDC8552CFC8D95C60EBAE1837D7A97CA137E9D4A4BD +2CD34AEFD68D64B3F4F62326AC429921D7FB3C235184FE0899690A0B775F1A566EC29D5830D32372 +6526F7E7F5AFDD71B77E07613DDC4FC63EDF49051AEB59E6337AC0A4B6DD872E776C9CD0CCB86130 +5322D816732124F5978A86C186BF0A0F88E733CE38E4D7C1BA5378C5629B1EFC97806059990ED42C +5CD183BAD7E94070E4058569DA2E51831FFE0D080301AEAB4350BA290318AEC582C78D05DD92E5AF +B4424EA808629BC972E68F4FF2489C245593F07555CA6A2B25964794CF31CBD3AE5C229AB9B8C298 +06C01D116EBD0FF0F159ED2D3D7DFC73EAB4910BFF5B0B0B587CD9EA6E6FC45D63C09766224D8346 +1F0588140B258B1729F70BAE7962189B1554483392988CF230AF4077193E53330519394DD99BA135 +6D4730AB221DC6A66019BFAE564893DDAD7B177DADD16ADD21D396CFA6C3DC818052E2F71149FD59 +4A16DE0C2FFDD366C99B486C55A6E991E4D22CCB15843F0C3363676AF2F5B2D1B7EF66CCF2F12DC5 +0D63776BFFB058D70A9C76DCE96C754872D72C82A0C33F90D49C935402CDD26B6D743B1F43BED5D8 +B539424849C1495DAE73044E885A7D0F307F1816DF6244A6F2D97BFD4E200E93F69B08AF39EA21E6 +E347A47CEEBF803F73B978ADBFCF056789BB8E6E2563DE87DD9A8C877157B934102DCEDAC54D487A +1BB2694F0034093C48F10A17D32E2BDD0C723CAF59ADDD1BE373AF8C9BEB4415AA5AF36310C31F24 +354A53C0B962573148BEF91D994FE3F3D8450DD4D686725799F53C373A0A3E3C060C2E1A3E800504 +9F26D716E1F381B9F83125E4683264A07E2D8938F605978E2513DD2050B3D8A1012797CBA8961632 +BED260916338A812AE751C7B657E086A0C7DDCD3BFDDFF3E48B84751925736D1310C4910FC114387 +F3ED7FE163F91895EBF55FCB425CEF5729D99BD8F2C072E36C310523E75CD8E5DE49C031C4263410 +9D56E91A46C8C8E89FD92012A00C33D0DEC52597B5C6933291A7BDC5CEDA95DCDA5600F9AE1C8250 +54E7EE1067458CCB66610704C58E4A4FC0CB5FC933D0322A716B2CD430A3AD48DAB3D4CBE9D23F2D +092368CFC4E1F5495C133A92942EC62118D45C17723646E69407B4A89DCDFD2AB3FFC099A21D9D29 +741D68270629AA3A414FE58658DC9170C247B6E23F35C4BC5FF83009F462F2EEF4DBAC5FD158A658 +57F9B6DC1F5192DFB169DCB65621CAB2F1B07BD22F4155A8E9E2B6388D430FDE5EC1C834D22EA035 +C52E1E34482EADC36B4CAE902AAE89A7284E62B3C84B608D6BD05F75BC31310B2DD3B2C08A00E073 +7F104F03A41989D5F6B9A2C38B22F1D1803EE5D7A4D8DE44E4ABD496A1DE0C0E12C4BC96D0122846 +3F0EA9CE9509FEE987139F3DD3F9D0DF4313F555BE85433718F6D05F197C41A9D9C7A8B0D2740196 +82D49F58DD5F66B12A6520D9F226D1DF1F1B65CDFA261F980CA25A92645B86B64606293F8BFDE364 +C47D2AF2C709BBE77A70A5712F2CC26F3D66F5BE2C307A48E6F887F681D30121E32BBD87271B5DC4 +615D28C309F15AD263FB37424E56DDA6E17B998B45BE6C7FC6C28E3394A8764C9EB2DF5C06626593 +B5C665D550D4600172791CD208AE9F37BC082B0B242B0A504B751B18F4D7495172B697EE217834A8 +A4FB7CC16D6F9E8BB400BE8AEB0850960283DCE725249FCC4DE97D9886745AB6066C3E2F64DD8AB7 +9AA11667F11188D7965DC11EB760B772E282DBF13249F31986AC6898FEBFE23E3E8B8D2C33E00EA6 +FC493850ECB2E6D831D1EFCA3C2EC8EE2E394599091ED58BEDE97D7A43B6F739EB0F845EAC1DF6B1 +EBFE876009CC5D804B15ED4B56761B3CE1AF59C07B49DC798A44532297AD73D5101ED47F36A3678F +818297CC27F6AAA2AACCC9AA9B6F5459911D8C56CF499E390AE607F3790450B2B9C9BE0F006EDA0C +715B5CA0481734CFB0597478E7602B0D2C1E4F78F03C68C17C70E4B42D7D2D3C95CF40F73488B371 +8E2CB05A549944D86944D78724E266C3319AF89AE430E777E95F0D792B1C654306E421F3D63A26B2 +1E74B6E8B21B2E2B9DC596D013CDA16D08E65E8F24A84B12B2BADC653E6E1110DE2E709C1C1BED13 +707B70A421B384F20CA7A9A9D20324DD383F28B2D3C7A9C53F5D4C6B7C378D26DF11CF55238BE1B2 +4FA70DCC178DAD3D35670FE4919085EB1CD905971D76A368FDFCF9D2F0A23739851A3A6D2E02D65D +54DEE69ED5D81315D3EA5E356F94EF256DD267FD1E1A9EDC9CD63E743F299BCC4A4506233B8DD765 +2CA067F741603F93250C087D368F9E9CC4CC1A6DED567487C05BAA992B0056A77F630A72008E3946 +15A9DB24FE56A956650EC9DE90A6C2259189440247970541CA198748928215C0E132A81AA13208D8 +63C1FE817F70CA573B54577D10B73100AF8EA088208A44FB92ACA314AE5879706180788C17BB1D0B +81B6B95A1C4E0F9EA66F9B39BFE12444A6446691A7BDB03E0F03D9F07A10A7598F2166F108529F34 +CD90E601FFED3479ABCFCBDE8F051C348E48C61D95B00C59EA1287423F05666C3D36288844067E83 +E14F6B5210842C742B89F13ACD126B9FC50ABE2CA7D7ED513D43B6AC7F41EEDA416BFFFCC5C844AB +2D23D4DC09B2D510504CE98D02E72020D9E669DDAA344C63A1B75632F912A1C0DA3885DA4AF7E243 +E4A4C6493D6595BB6D56B0359106957259E59E336BAAF35BD1CEC5CDE735272EBCCAE8D4904AEBD2 +B32610C6FEA2B69941D6542ECB44D71092A3CF067708A3D087AE99FF29671AB7DD8758759B971A08 +AE1BAD78270D2FBEE37AA2DCB119D72F6C7B0C8509018A70D0B0BE2C6830EF8E0B24B1CE1141EF87 +3A4D7DCC501F808BFD94E4DC0F2915AA023076BCC8006490A43685EA25AAFC187302EBDE7FE1965A +04A5A398985D29F08E085127B56B057334D88EB638A4DDE64AFD204974C3939536B1B66A54B4DB81 +151853915718F70813F096CC1B0EA25E363B49264C2AD17158A4489F91453FBEDBDE15D7B74D7F98 +E81DF23251785D58295BA297F295AA6248A912CDD4F1111E6B628EECBB5139709E76EA4AB743CEC8 +26621D08E6BC64691CC90B3C3C1778931A28D3D5B1E20E96C643316613FC487C9B604C43463FA453 +3BCA1236286E6F5A6EEB2F1D9C34BDDE4595495A365F88055D9268541CF1654ACF478D384A5496A8 +772EA1402751A093582A6625A0A44816B5FDBE166835D598644296249B92CC90AA3FD6445C9A19BF +27F59CB0616C7306070F33C7DF4E1DE64AC8C5BB2FFAC1EF2B1B30E5A0275E6004CF64BBE2C6710E +DCFC3AA4ADD60106334708862FFA6652825BC84842736E47AE6917180365C75B27505EED3C6108E9 +898A780E20C3F606A860229AC46D0471ACA0187D6D539A1B8820F620F72B41AD1D3BF3834BF48CA2 +AFEA8BF535AF74C4562DEADCB63D2F5C7585722B77C989342D190FF926C8A5263B4F25286F99CF6F +C62EE6E2AD61C82B29D82468AC10FD27764278E5558CE8B41BA111CB2F040914451A480C93084237 +CAC8F66BB7C6689F340B8ABF0150E06D5B1177278A4C08742FE22F42C28680F190900344ADFA486D +59718C25D37275BCE4DF981AAC35D2C7E85C72A0188B8953CFA516FD545AEE0BF4B8BA301CFDE214 +4241FBDF3D204E3D2823301572E23F204C97305A82401660E12926EE7BA6EA1A81FF5C007933AFC7 +3266FAC4C134ED818A48E7DA01C71A46335C845F9DA5E960B25339D551582B375814148D94CFB781 +FC56093827B78578A73D4FF67B6B87F40CFA5E3F4325D9108CDB64BD06427B88C84105187316FA29 +90B4E3E8EDB6C78ABF164F4A9717D523794B2FE772A04DABBE688CCA977090979B5F47CEB90A1DBC +167D305EAB231C9F4260C4AD10889CB785169902FC0BED78DA15B8417453BB65856EA0BEA5245BA0 +573F623D215F6C0CF801851C305B355D26B52B0B343645FE25C78A3526841EDA480919A1BBE5F56F +C10ABEAA3E1FCCA7C43EE560F067F1AA2AFD642F769D1ACE8E2AAAF38850F0D757CD808C921D716E +96FBC07DA7860DFA70CEAE2888C0ED3CBF9586443532B68DAED9A926655C157A416C383A53D8F283 +2A4E67468112A09ADC837ED8EC95F70852921F50D4417239FC42EE3624CA97F682745CC5E76CC7C6 +7BD99F2180F8C0B7FB49539C8CC474C25C0DDE491671FF329E51BCFA779346D4686835A3AD6633FC +B5E0F67E0CA9CED8F215BEF4D240453EB2EDD6ADB22278AA5B985FA140C9834D38753DF2014F8C0E +E6DAD19E8FC54C03C1F6CB0F858986691D99592562CAD95FA0A5B2ABE4A8B54B457D42E8C33A2D19 +51C0419A72FB94FDA78ECD92BD2A1416459E9DECA9469F35E4C47DB531726DEE8F203D7042EDB32F +025DF3D582547BB1D45F7A5B70D317DF4EBB16E36B0D798E0932FD2A85B04FD67143E4B287A50416 +2C1F5A037CCD780088C5476385AF8168E12D97D44B0630621759173C8F1E3006B5B1C6D7138B7EEF +C3CC5F54E24B2C3CA7B41AACFD25E554880AAF406EA4C3C6E21D3B550B040FB1952598A7E8E6488F +E38288B2AEB6C4718338598A2BFE4D2B9D14C65732DA304C16FF3E1F8F03046EF095B65FD609DA87 +EC24A69278BFE65C905CD0329F6A486B8525B7EEA4F7AE56C2633CD83543269E8ACD6D71F500D82F +DFBDE7F7F7B1AEE67328549232E26CA55085B6E84D9E2E7F74068F93A90C4654F2F396E57C5F76F7 +E61CBBE523DBFBA6E76638BBA3064DA025A79E3A294FE7F1CC28A3B4C57DD6FDC48E541A85534B25 +E1BC11B4F78019457239EAEFD4BE9007D205F1D985F389DB22400B279C10948551A6B4A17FBDA0FF +C9428B18B43DC76EFB15FC2182216F1B60B4E344A03AD6C00F141EF99F89F24C819C3E32877A927D +84C2D006940F39CA8B71E5951673EA9BFD1749923219DE38929ECAA9CE43B06CFA7DA1BBEDFDA56C +61FF6C24F40E59B13870D5FDEB82D981154FAE5D6D5152DE69339359461A41A9713B6BBE47E868C9 +33CD74C75DB71D13BAE4DEC85E02FAA14EAD6C0A253B16C79514657B15E68CCFF9EE6AA385CFF9E2 +C53D9AE40F85C793E4E8FF50B2B7420F4FE69807BC5F37C3E300E6B3C3549D1D3246A2E70F091054 +1135BDF805E0A698E236B6496702D061241687B7B8D1A0E517DF0476DA09D89667A7AB375FD2672D +CBAB8124E511502DDBD08BA04D941DF1CEBDCCF7ED48405CBCC33774A68C5212FC6F132641FF413C +984F8B43BDFD7B1A2A3435F15AF07EF4970D3E4A0BB947C181E9CA27CC14A35BD1BD096875B45873 +8CA244F88C28728B74E25CB8C4FC1095A56CA75E4569AD3082EF194ADD11350DB3B74B96761D4538 +596FF7243B1E1B724716A144106E080D42036444FD472998460CE9ABBD05B42AF9389AC452BDBBA3 +A13A96890025789F16B9D92251FD3B3BEB2C61EDDB370A20456E3BFE5F4039E2557C451C524F8087 +015BAF3FF05F51869FB97512968BDB2B49589C1C7AF1E085250A47657465F480B7023E24C76731AC +0EAB6704123D77977D3A2C4C56B691346EBE589C619C04515D34F81FC6A17527D5D8319013C5D4FF +27CC3925E24C99231AC7FB9EAF0BBA482D3B75807AC85D03CD09DE5D9AE0B07B7A813F0449786500 +0AE8A7E00080300F0AB8C399057EDDBA273DD2E1B2A0DCEFAD3B332E6D4AC1FFAD846167DFD70E03 +46DAF84AF292D4F424256ED5AC4E104F80697050D50844A708EAC9E7F7784FD01646F3BD0C595CA5 +1EE6BD607D254E78ADDC5E15C3B6AC4940EC865A5C23105B6BE09EA09F2C05D6D76960A843B81EE4 +33977FAAC3CBDA85CDD2F4DB7C28293A77825635992AF8F3B38B4480D9A139B1662345A8ABE1634A +77496C3F57597D2985E9E54717AB2E99CA35789441BCDDEDE9A9E2106B401D9684ADBEFE40D607F0 +75C179E9CC03E59E65430DB70B441D43DF03F2AA6FF06F224B6E455B01C64FB89EEC9103E48453A9 +749B4D602808C7E408A8903091D85E06AAF635D0D529C3CDD1B8479AC0F4208C284BB678A547F2BD +77BB17C86D4560434F7AD1937760A6AA55B614CFA9FF8C9C96561AE6C8F2121C4E20237428BC51DF +2099B6C49E3EFA18E6D439E6E6981E746EBB1DC461259D8EA0F8099C47CCA27B2D982B72C9A07CF2 +1B3C05D6E26E6E286E348B8944078E24809F9C5F3D014B4CBA02533F5621BFBA1F0EDB776C634746 +703C9F73BA89B1960A496420C68F54E5B901A6D733D7ACC79F275FFFB253F389AA480084468BB34D +A1E797E43B7F6E8CAF5E8C93069A3A2730E57EC39B677BB73E3F07C2055599F7062E53B37A5F0099 +907D2ED87FF7A82C95FBAEB888033BDFD67BA3A6031A4CDC56CB1E4CF5B06B46E16D988BECCEFACB +9E1C037023D7BF5CCF5D65AA66A17AB361BE7981F132A578F3ABFB97960A6034F052D9D5AFDC0679 +782EC90F240F943A5F9A3D969ED7399254FF67D89DF668F7C56FCEA1FFDCF20481474AC8495D3AF4 +B6D7EE093E369C057F0B70858220693B398ACF8E8143558132E4391405E30A73937C53402E459F4A +A3539CF7A99A3F51C0307D045DF8B77757E92EA2F51BF0BB4F77D3904DD355665870C2B59F1ED7F8 +4FC71FDD7F0B6C5D3182DB77827CA6A2060D2B8C83C4EA4A432EF43A4D0A952CC6CBBE52A9F0CD66 +1A538973DE41FFE9C5CF55F2506B9EFEE51FBAE5E63BDCF5528499A47C031163C88D3022606784DE +2F46A9C9235AEE3D4F71D4959B0CFDC5B7E78C8C0A8F9DC99440C2263DBACB343C5C648577F5610B +50EAB1CF7FD02419EF3941C7CA0B0E64EBAD4B2CB05A0793DBC38F1946D44767BD287F5E9779C611 +CA0DAAA1E7393DBE0683C8D3455CDFEBC0E64B54B737E298DDA605227C0C4BBA87AA3EC7FA6EBAEC +39E6EF2537D5974391D31739D9FC42983D81AEE44711C823F35F8E2321AC74943871739D2DBE9748 +FE68592263E7713F27E0D49B9B5CB7A4E55DE54E6B800D15856450FFD3AE5F287B12AE4F438B20AE +9E27E6CAA00F3EAEADBE08432684FDF9931E925544A680182602A3C1997DE5D0630BD5A010535E66 +E1C123013D23966B3545C7431C39B97295BFA4099D14461004C42C85095EEACB9B47C593BC6DB863 +533A8619BAE09095DE8ECA432D4DDD49AA600D277E75DC3F5C6631E2A05382CB007825FADB77438D +CFA78E252D79B6A196D5164C2FEB85D75ECA25FF80B1D97FE10E87960CA0FC47C41D3A213BF141B4 +8BC3AAA93FA86245064668394665BFD52D12C3BE4CE39EFD8111754398A944C3FD1AFA98EC337BAA +AF899D35E804CF416AD7FE45FFF13FC6354007501043F98FE8428DE8013901BA6A28711A2CA85A27 +0BB135B72F1D5026E8217581860729E94F2F1878A0E96C59E9F62714FB5F8F25003DFC7347E99007 +8A9A331CB3A6A535BC61866F02513DEB982C4A13ADBFBAC3FF70A7335F40D5489E48E5EDEDEF1619 +1973D932479C62183B0E25EE8C4F76D4F1AE45DAEA4A12AEDD9EF81D248E8D19F8C8A5BECDD1EA1E +98783EB7A38149170851B1942C96C53DE06DEF80913BFC04E539EC67C110498D15B78268853E5C72 +F485F8A27B768569E54241F6115875E2973292CF48FF91D45EBED627AE9F0766D22201B20AFDD40E +5B17CF337F2999E0BD15B86E46EB3C18FC12B7DCADCF9DD50C6C7E3F37E615A892DB3F57E250A072 +A49F7277DD6A2C8042698233D35A699B17ECA5DBDA6D250ED4A16FCC893BF0DC2E33FB1EBD7DEDEA +3C1C39603C8B7E1A5A833A8FCDD5570BD088749BB232615366687962C7E56ED089CD7B092505CAFA +5A80F503C4CF337F07ADF0D106937E25670839D491F7BFF7A523DB609D126328C16113ECBCBF9C40 +04904427A108618AE5D4ED809F8CCAF72251104C94EC5BEE21F91B179D31DBA79CEEE5EC7FF698EB +84AB1D2D1A624F58B3622A78844CE51498B2CEF38EAFE259D22C7BA61104651A862008BC1DDDA58C +C45F663EB26428DAA85E7785363A69D2790996EF5D9621D53042F42F794962FEA46E46F37B8AD1FB +76FC8D5CF2146843F8CC625139C75FB42DDA71A752BAC48F294E4C0C8289FC46DA5EFD9C91BDA6D0 +27518B7E81E8B21F755A9615627D5812ACA674D1527A1185EED4E3C628196E7D0759B1CAE6B9B7E9 +01E9599A65230F1EE469CD33B9BD9C104C44E3C1AB966C9678BD0AD78111A4E0F2D07A01A038CEDE +7036D0534D684A1562A17AD64A00F279200C0371B1CBA61747671D2A21D3F9646CA290F6B82418A9 +6FA177C6278277504B7FBA936325F5FA124AB018A15DC18D2C5E8F93CDEEA52BEEDB78A57828D81A +3E6C38B9FAF3DC4EB7273ECE3EA4482A1C6242A335862C2C3717F9C9ED95F77B140C4E1569B2192F +C7DCF702D0BC9A50428EC406F8BD0CAF886B4D979320D3E429816D88F7C7146D960AC12E70F2CB7A +9F4E3E366665AB3F1B4B6440F55EEA26DC9EE0096BB7763731740A537766490C8C174723BF0EB40C +53701AAD12B21D436ADCE22203C1053A9DC4E9F17AE617888C4B4E6F3A720E4E6366BA628221A387 +D8AB15E04AD69387C310D3528BD2FAA5B22BFF3FA494F5FBFAC4F771C9C7402B95580C5AC4BB3AF6 +92A70CB2C851FA5CF1173EEC3EC29B5A05A0B728BBBB51D3B7AD8B0AF17A1563E82FAFD93F8B7118 +1FB7AFE352874F4EC6D334AB6747519AB8E847B7BCED33EB5458A828E074E74BA621BDCD03FEA604 +7F7B6ABDA01FC7514BA1AFF0D4D0C0CB8F4E42D5A87E395D9ACDD02CCC220C157153422018725846 +009A3ACD8C8CDDB66BC6836B4026FD9F526AA275D06C813179E5924F26A25094E7BDA8BD26AFC4CE +B41D8964D4FC4AF1DFB0595BC5D6714C32F15DC7194E9A3A73013C45D8FA55CC0550A12D9AAE8E9F +F199FA28EFC2426D8D1DEFB93A65717AF3EA8E2D5B4AA8EF0EF38E9600F7D4E7D9F1D67A2E63ECE4 +789FA74B159BFE2F91C19B0378BA52E93DF12830D99553B6618645E26126842AB70262D96E35E5E7 +50ECA0CE3458B3E51BEE2F21191136DFDBCA39BDC07939E521E4F492F392DEBD029C1EA237BD89AF +76BC89F618D530160AB16269FA6B693CF14BDC4EC7C630025703C5337F61458FA09104EB15C7CB20 +AA4C9BDB7CEF3A09F25BC7F3149951A7CD75372993B80CD2112F7674CEFD6AFA764AA3486730D2C1 +897A264D82A91709FEC4A21E30D812F558451804EE6F3DEE2C4C437846BCBDA07C5B6CBA1D94AF02 +9163B7383CAC6E088AB1DC14ED3743EE77E26EA7AD3119A76C0B5F925C4DE305CD7BB3A09A453947 +5B9BD79BE28FC462D8718CE05F9D94CAF3387BA55E6E447BF81A9EDDD3A34E17BE66BC52B0C0BB6F +86F6F008829173816D205182ED2ECED319864A796AB65D4E3950288BADA94FA32B6F453AFDFC6C39 +A4FCFE60353A64627E2057D4B379D3240012B3BB0ED0C7876CB83C1BA5EFB6E2A03F340C2B576731 +F848F762A7E1CCAF267EE06D621BC33FC245D0E1547ADC12CC0EB58B26BABDB8EAE9CBFBAB93836F +FF22BDA1831DD01B7346AD377AA298D84628BF1C07433284B0A90FC89F5AEB2651BA2CEA405D4F52 +DDC0E74B871D43F71EB4ACE0D2B401F9348EAC3A2EF0AD295036BF6CF6F870D58E00B619D50EA7DD +77BC28DEF91D805CD527DCBCFDC16C042BF9B874E3B1567EBA4C1E70744B9E7E5BD1FDA6A5FF6E10 +1613FBE58DC46CFAC1A65ADAF65E49757E9304E2AC9A91E0588600C709A61D4231730073A36D473F +518A145E141D0A5A494441B9EA99AC23F60F54F8127B477E1CE698BB4129B4B1DFEEDF10D9E665C2 +47A62F112F5CA30B0AE5DBF3E495FF06EB28EB438CE8AAAD84D5F50FB56A3AF002C23BCF66ABC270 +7AC233FC0F2723DB99D2CFE7D3B3667732A531F5DC315CE74EDB9050BF75D29E6430F57CB6778B2A +CBD57DFCEF896E6766C8FC5C9F9FBD701CD62CACF33EE0FC95E78DADD205B5F42CC63024624BAA0A +B4DD447832B4E1DBA77BDFADD223989F8E958C8D759AAA37930664C6EFEC708116248A2A7AF3D656 +DDEAFD009B7F5333854608E67E5E588A857167ADF9225CF6C641F5E19C3E08678A281199EDDAC831 +B57223B1BEEADFDCBC8F6F25D32FCA2336C808162E8F381656E847FB6CB13969572425AA05AC830C +33DE6E030F86A3A85D2A66A77F103C7042C97205526DC882EA9A00EB8BD5519847EB424C15F808A9 +1652A6CC89B66A5731126DEBADE123C63D88A2E550FACDEB3886FF98646000C64B3A91078012CA30 +904B71737CEF6BECABD43DD702880538F5A70085E6CC6015D2163681067C3D513A8C66032C34A0FE +17A58AD4BC97CA69BF41F11D5E910FDFE9729652D3EA21F8DD8CC19160A8FC77573B1E9CEF4E790A +79D8AD6723B6804E9616466C935303E063DEE29CAA6C3BAEBF278B818C2EC2F13ED645AB452397BF +00DB8B26E115026E256746CD0C78A959364FDE6DEDDCD0F441A61A1EBA32C7BC172BB09512148D1E +BAC9E791B7D51B71CAD2DC9B83B2F99B3726607D9CBE58B499A13753CE87FCDCE21C0AD0528ED0EF +B9B2C927F57C78C626248AA2B835A0791244C5896686A66173EC9F802C4C633A42B086334D2A4878 +0E53D00809247BE64E529F96AD2F8B3922A6097D414DDE1EC76F9552F9B8D58B8E34F359AD792B2B +E50C26DB05035E7497162E7C49C38D3CD9B98D620AA67492BE5AFCA3A81A7080185C7F0B5105223F +1FA77805502A2E8C5FEEA27699858D84A95842C5F2FB68686D59FE24091FCDDE139B6463BC6C7B1E +0E90D20A83651AF00C85797BB9F53ECEC1675C7EE636D0D9E77DBD8F89670F855EE4D4800FF3F695 +0EFF09BBF8A0DAF6B8242840CFA5BA73BEB95115F4A78BCC02D85ECCE0C0F2EF6F328AD1DD6CC049 +5A3315B414A4D61DA50DA46D7ACCEFF6EE56451805D26B0359AF193531F95F6589CEAD6FA041AF15 +3067F88A0A2FECD135C56682DB2B45A71D1FA737C064EE9A4F404BB72A70B3AF0330359393247EC7 +81512482579865240A23CD8479F21C2C44A119EBC4E81B308DD8AA86E60C3DD8ADA50E0DFE8308EB +1A7F201EDE8DCFDA405AEFB47E0E6CA7DDB376DCB21D37F7ACC4D3E9F26B03A8DE0E8940CA3A9E75 +963A389DF8038D2C486072F61C0CEAF500753C7A6352B1CD0338D9212B42A4D3DA23D5BDF44C27C9 +4B88A415A3242FFE2E1B332477A21D2B9CE075EE479C6E657A4D8874A8C53964229310E01ED4F3C6 +86FEF5258EDF3B464DD6FFD7F1CAF473BBE722D60FB14AB4918E93878A8AE4773930B8CEE110F476 +7F42A52D9304C55BE12846C911A10AB9B2E036BF9DFD597F5348D42233315FA80D0F563C388BC253 +2103F05E90DBF1923F229F980A2F4585C7A373511372D07DCBACA583099EA972C03E5AA67E663882 +6DB134564DB993CEEB6E7A6659C7C5C05C310267D5F8A24EEC2D5CC3E3F3C808E6D6068D1A57646B +37FABD98ECB7BAF99E7D9AC4414A491A73CA34C52F394352F6B5A15F0FC4D88622DAC694699C2464 +84ADAC3B1D366AFEDE2A2CD2042C90516A666A19A91C80248B11224BEDDF1A320E230739E755D098 +B6A67315535F4C187CFA67ED817A035056353FC859BF286317996FFFB478A2248B908FF12ABDE705 +402224A3EE5F463DD3D243875C84E02DB968ECA1CC52C75171EA50D6A88CA91327A7AA5795019F36 +C0A19C093A1C9D3723C7568F9D41F2E4FFB712FD47F897703D7A620B586B81936C84AAED61D84332 +B3BEBC4F95B796B93EF7A1F565C494F8A65EDB21E2EE18DC025522EF8E599887CA2836069CDDD889 +88E5862977B7472584303198CCE97EF9F9E1446D1F1F5ED1CFC666A8A0C3A03E1792EFB60A9B4065 +49E0DEDF6ACCDBD98742568B4735A747D8E5DE21E630125AE0C691D054E42199C15B1F80CAFA6E7B +B2005F374A9A5F9900ABB7409CCD50C3AFCCAB1214E6A856F7C7EBA89BC3291801E1343DA9DAD2C6 +ED075C8ECA1423B43E587AEC67E6145272814B3F191B3C285639F9E2D6E148A02DC2CBC0E054D629 +5CD05DBAC1950400A9189316F0265B86A732D302C5BEE8ED233768F237C62600CBAAFF3A110D5EFB +6CC7CA3B92D965CA7C5E8D3E64ECF239FE2507FC797FDBE54C1112B28D4DA44C60AB09D994C5BA78 +D663A2591934CC052BC70CD1DCA3325C66C9CB982E2039F5DB70C848D3DCEF655B1C2CD0CEC8865F +E8E1C0A267BE4F707ECE6F5A3DFCA3CC1EDF92C760439F51AA69A4C1801E96CA4D6EA4AD980258F3 +D15C893913ABCE09101984C61B91D603053E49A97CB82FBA707DAE8AF1D579FD69C8481CB7B712CB +CDDB4D287BE995E32C02B399602A08B9DD849039B5673F1930BEC7BF366EB082D2CA5DB2385C8CC4 +5BE3FC0E31820191A814EBA7C4F23B1938E6C4D800732787CD2CB97F762DFC85D4B798809B5F2254 +D826CA42B32695428D120298B44CF38494E56240B75DF1E41E46E53C44DC505452256DFEC819408D +605FF14D6C1F3F152F2FEA96EA0AB3B472D8704E06BE9F8C3E8395CAADD06D6DA033E81ADE5DC3B8 +3DAFF743C6E9E48716003D358DF63CD7FD3E2F727D1F2D0C29962F76D5C95ED44B6F08D052025A66 +5785F264A3D5F5593677B630E628B5EA81FB37CFFD7A30B7FAD226B6FDC82B0878AF4C0EC4F4243A +807B9839EA62BCBDF7C2E9B30A623876E632E084EBF4A21EDA04FC88A1C07021D0C72EC3E969D449 +FEB08E5826EC20E55B21EA71EA59F6E3B0710B0DDAB3261B4A2029ECAB68C19ADD5174E55D5E984A +4E5F38F592A302FEE6ECE732DDE841A28672C620CC5D687455A5C06FA9FE688394A04F96312ED025 +B7AA6FBCE2925F3AE559CC1886BEECDB70822E2E5CA3F732A87404B1536AAC469989E9610CFA440A +CE43875A70CA51F36CB6F629D9424C1E35A88F92D5DA3CD8CBAE6E8425A36968E21F4F30349749E0 +205BFF8D552837D6FC39532525370BBAC833F75F1854C93FC533A4AA53ADF7008173A70D94A4EBF5 +38EA9E62BCDA7C20E0A073BEE2EFAC34D2EF1D03BABD5147659E50B557045B2EB89DB303749B04D3 +F54B43FED612FCC68206E001A7AFE90230D9C12F74A32C7EDB5D0241DC3A5D51481FD7C8FAE08FEE +263FBCED7C7D911B3A303C835AF5FADFD218F61A9D6DE80485ABCA88200047B094441F7767B97A24 +E8C612590FA2407BAB1E8B56C71914EEF2355DD97CFAFCC192BC06FCE063D3D9D1A629AADC75E3BF +207234C208E7E30663EDD691043065C9CBC473D97C6D4DD3DFF59D6A9ABCDD4412C3128F603160AA +D8F81C6E7A4DCAF35F3A99B4EA10A34375B477C2BF846521A7EABD4D28078E9340452A198F3F5ACC +3DB7E3908939FF6E3709C6A3FD9889439A4AE3E10B618CC92E14B68429A3AD2C80940A1079452EC2 +66F254657BE7D79A2A24084AF73F6DF71FBCD32BF6913A3FAB25F977787F7BB0C3A3E8BAB38D7A2D +B0B4826950643DD1E03BD7DD1FB149A33862A89226B7CB454DAF613128C2075470E42E70A9444A8E +6ECA526345AB48E6F5160BA23B5BDDFDA6049EC44ED1461C7E0DD514B16E2FB285F72039DE3C7982 +EFD40D7F6C8E8F4CF35AC71B467BFC578002E8D2239A2FD2C4BCCDD8AF3D7DB1F4AE7F2D2E0811DF +9D0155BA6EDE50B5F052F14F6AB884FFF244D8806C07EBCB49ED22D85DF696995991A954AA97A1EC +D86ACD76E061B7541E87997FEF0657A826BD88EF3A4A5920462C6595E7A156F453291CA044CED810 +860C3B0149BCE73BECA713040664AD0591304106129600AF71317B0D2907839CEAC99515D357E980 +B1937B6E1200AACADA205421001F1B2F91753E80D2263C56AA164A74701A8D5FD28E46480B0DD963 +A683A1F355D7FB4463C7347C94EA5E2CA40B60B56297CB22D972C5BB10E56715A955605256C1541D +9F3BC5768A6F355CD3B863F0FA1A781EDB49368F51B29481CBB41D4AEB07AF9DBE8F52C5D0FF75F7 +FB6431D37D6AED84D78C778871CB0F715B4F07580F23B586C969C81B471FF6A6C7276F7E141E02A8 +584D4B9AB00E7BD643D2C3FAAA299B1F1E25048461952EA42D4882768A70DE46B213A287F8D31AC4 +6D5436F22A796C05D1FE50A9BC2A928066627A0D87DD57A3AD91DB446404B41557D1457873482005 +EA20916BBE46C613F456C849D46BA79D20627B446B2F49E3FA309AE14F8C420CFD94922CBC0FB9D3 +5A0F7DBEF577F1849A1A80E0011DA8AC082A8C6F61658E65AD177ABDF23EE17C8CF0D26B9FA3A6E9 +4837EB9E930336889767A8D7EA3CE980A8EA95528B004957BE6067CD9BD8E02A0F23CC1762CCA656 +D33412FF45E917FD4A03EB6E8C1F43FDB0A8965A33B4FD26BC24A20B304CA817E88495BA9B361A3E +933717FFB0271F7F70C5D3CBA1E86D0F51BF3ABA194DAF32C35C796627D00C7B2271ACE2463E37E9 +7B3C826CF3DB60028F240F9452CBE08F7EBCC5FDB1BCBB3C327A9F450B9E5671916101D6E3E5E458 +CA31F04D12F592F83BADA2C3683D3886AA3B403963AB5DBE220FEC00037A745839F67A3635DFD3BF +F08F367482962DED88ECF6322852D643A54D5D303EB04BFDDEE9BBA1EBCCBA7C653B3A613A8E719A +DEBE3CE1BD7E754E5F4977E863E3C2D388A65227B451D4F3A4F94E06513CBA4AC1F2F511613FF035 +611684CCC461599000E546E4D972CA6960E095A526E4735A23421A4C9B597ECE08AFA2753592BD16 +DED93255A1E33DEECE3C5EB77B94670E8137F2A4A4B98AC193258E7DEA5DB8408A806188F2D1DDC4 +40CCF0E9A6E2F0C78FDBD7B68DD4939D2458C1965BF8BED4564B32462FFF3EC892C03B11D3EA813F +AB4CFBE8D3016329C5B7E3DFED0F08284D44AA0B7A2F6BC96EA4503E8EF52A64C22BED6B452581AE +8FF8917D53976471941A9116A2D878FB2541B561767ABD4E31CCD8A590CA03494C62AFFD64EA0A1B +C779173DAD84999C7A8D844EB1259DE7BB5B25CD023537A474A524EBE4660B22568949E624D8FEA0 +AD37F4CE1EC75955EEFA49C6BF1803BE87E9C9865FF3F6B8525B8C15FE8835CA153D27E6C0FF0CA5 +1029A7A9185D25F0F14D86FC797DCC1F99EE97E2054B9C2A2E06FDBEB8DEF6CDD368BF23A858D9F8 +C1DEFDCEAF1B4A8DE5EAFC604CECCF0D285BE00AA912EAB66EFF4D37AD2EFE34853BBFD87CE09B18 +749B489943EECAE7887B006FB827D10191DAD18466CD1F86505879310A8B171F902EA0C26A388E13 +B53C700272CEE2BFB47ACB58247C13449C6BB9D01232C32517358F1A3DE064D43C18F8827D53789C +CF3CE2EBE78949A6ABFA1A6B8414CE360A5E22AFB7D1DCE6F5A06182C3B984B4F9BB1A905A9D5A14 +83750A1DE0A857CD5C06945EB7D4A2A6BF1237F32A154FDC06D51A703D44FE052FD3C53E9E8F417B +35D1C851F9203A8997521529F21AD8498F96930AA77EBAF82EE02A57BC77C792D9F220294B45F48E +A8FD94E01CD25645D36D168923562F3FDC93CB79DD4760DA0C103C2675722D7A1B79FCB4245ED12F +A0DB52492C9CCE58B333CFEE822812F7DCA68E802C451B5CFAEBAC608B950386B6C58239D1C62D62 +4DD5D15782FC552222CCA06DDF387B373E32C3C2864C63C768350C37283760F3515A5B0AFD66C48A +B522EB3E808C061F5CD6BD96CD18C9839D30508E7D4EDB88E8F11E31E10919B16B7971F06D7877A0 +58D8A4944C84FC6CAEDF3341B48B6E0D3C7B85D710E0C35F5B5053CF4B4798B3778CC28B2DC7AE0D +F3A49F9F3BCD8E95D746C35C3F47D68B8AA35D97AA08E711B5FBE70D1A623C82541EBDC51A827D0A +69E6C049087AD26F256EB7577F58CCFFBCCBA5A95D093DC29464C9A38DE95BC6B1853963B2DEB0B5 +7AD1248D6F1625E115EEB9510B5772AAE4E3C866657DB0B3BF0E0AC345E116F8D4976B770876FFE3 +748C36165522991F46A36F193DD1A1C94713673C7E4C81582391B636C72DE94CE6254374F99B623E +5686C13D8A8322E83E11BB0B0A896C6A8C2C4F756C5385CD7017F26D23F7C3EE97372C868C8C9155 +81723BB6B76B4C3CE8998E4FA6CA40B633DFDAA59BA902A4952DA90EC4FC3CF0F2676ACFA7F76F78 +236FA2DE10FD3545357215246BB7E527F277C28B353CC6D79DCEF21BCC8F77603CDD58A2CCDDBE3A +9802F941CED8E035313875319548C41992A2BE939A17CC109426E33825AE59BCD17CB19F50D972FF +CBE7D9B4B0BB095303D9DC9D406696C2508D6CE99E11CF00F6461147E97449ED5F486D480A86D3A7 +ACECB7E9A945984724EFC21C5079B1FD03ED803C2DEAFCE3327D2D7827715FD65D9506216C88B0FA +26935E95C64114A51919D419038B1A7E9C1E829FBFB53275093752DF19891A97F3CBF7719C1FD6CB +17019A6D2D25360ECA804C4B35172662CC4769D2B785C6C87E5A4ECCE31704E59F71263B7C3CAEC8 +ACB4C7426EC25F11A0042323EE6C3EEB04284DBAE2C770BC419DCE79BD4560AEA41571C3B595F525 +60191DC7A8FBF63D413A77A0905E517441B16C2B501EA2F9E99CC38D052679F288FDF1894542E3A6 +6989A0090185EB2E75134BFA3D9147C3DB8A621D9D35E37786853779E157B47F71626D6B3E633005 +9159C17596C1B87FE2B4FF47ED9D78FA4C2160077276C8B58CEF5DC030B4A5D83CF257096C047FE6 +4DE307C598B815058E72D5F57DF5C369E664E137DE29349E2F9DCD8C9F4EBA6E765B6327D7A20DFC +B20711273FD8091CBA605C4C494248076F7E03DF65A6A50164980BBBB708741E5BF6056E6F996DC0 +7FFF408C5B8EAB8DCEC315E92873228C805D4440A6470E3EE3983758DD211C9CECDBFAA4C9300CBA +00608A4B2404A3C7AF017A3B7E67F39F0B51ACF950D3E75CC7BC2B8D3480202FA958E8EE0B240501 +5232EE0D264C7CA02C18CA45CB3C2DE322D3EB7F00F9455DB6C5B1F4E59C3E95520EC36D7D903CBB +625D70B54BF6F8255E412604BBB29FEE026CC660577F91DB1DB4A613EEEFB20CF7AE3CD89D565AC8 +38416B01B5DE4FFA5550D17FB51FBBEBE21CF1D56038863EE931B90DEC2E211ED42BA92EC244D4CE +2C4EC5CA87A026992772DC2AF754FC982B94F36EA7B7BF75E0ECE90CBB2A6AA1A012E8898BD679C2 +3CB3827C35D5D02F0569C7AA82615D4AA67518ECF668D3B57D6EF1A8013424AC2268BA0D9A74D588 +79EDCF6382A89D397864940303EAEC45A38304BA8B1CB198967AE23EB81054BE74B16909A405E8A7 +799CEE3C270FE2A6DC50BD7370B6B2C8FDB9A87D88D5D40348D3984E39C693B6F4486D994778607A +80A3122872DD65E40492107C71C3CF708A9717E9EEFAFBDDC239C53AA9645B711038E59C8B861B37 +411AB2039BEDF9CFD00F08D9C5D76154427FF5DD39878CECC5D7BFB3F1F035087185C0981F3C2139 +BE84872FFAD3408531C4EA9387B89F5E3EC779E8850D50992DFDCF9132BC551E985943B07618AC10 +D1150451F0844C0DC41D6E17EB508DC8689EC726400D5A7F6FEB3CC7BCE05F09228B7CB2C5393664 +D8DD9A4B96B1020EF25D70AA2D91CAE93AFB5F2BF0AA18CA5C599FA1A708EF35BF8F7FFEC9AFC1F2 +42870D028B2B1459063B493943EF1283829783E1010242E5CF4DA39D93D506F3892936E7D6CF1124 +70A521D397438733D053944CFF12D6FFAE8246F20618684F263715AA98E15D72A526383E05C23214 +B78338E5B476F0981D90056E6E5D0DB66B1DF2298E597B2ABE1D817E18BEB056E65EDB4234342D96 +00470B1420C9210419D834E431B82F58608C87AC361A02D0F1FE4B470A3D71E0D21BB87E1023D428 +E23D596CB9E1A2184403A16E36E644BCCF9BBDE27290485057E62827283E7380AF786BF395B3961B +A5EA469C315763FA59E0F176EF81985F38B882DE56A74D128E256D1B89939728E55A92ABA21A6B78 +44FAC1BA7BBDD8B34A18194A2984B000380FE9F672E83EFDBF276FE797A325815B0F25CC95C97A9D +ACF56D583486305D7C9E51A7E337D14E3B900333EB38FD93A99587DA2341B10C059C71CE080FE753 +3C0F059FA40E560AF9C4A41A4BE6FB45846FF8F78165E10B4AD40F264BCF5596A1E8EF8CB6EA4B1A +3A5C69059AB1563843679ECB2511A90E8898F54295649CB73D277760D8D04ABACC7BCC6E777A0530 +E2067CCBC08673F9C8C178F9D672AC8A15E5367F0C5651B53E75E0CFA57C931746AE1A679C246D7C +9417F1CD89DDDBD1173C2F880B7B3847CBCCEBF99F7122E832D7C9BAFE2B54CBAA1ED48158DE3F36 +238B76B0E67644A28AEA996DDC006F6AC0242E4B667639E7523CBC90A0561193C1AF34481C2EF402 +EE43A82E1EBF4E3D601BB36B2D95CD93550D61CEE7A94E72F6D30C32C8F91A61E964B1F66ACFC398 +7F95D4028F116E9A9A8474AA29C1C1A984BE0E393BDC41DCEF6A6F1018DB60D52024899D8EB5D55D +324D73F39BFA47377B9E15B3B06A7585589FCF52A54684173E5183367E7B0952DC4BC2767C4C6247 +B1D6103E52BC7B7EA6298F454C5D97AC575F19C10ACDFF4E10C7D3755CFAB4200CAC545269FF1D8D +B0D607C7AD47F40DDF257AB4E7D0750577003C13E4941960C3DD7B0774DDAC18E8ABAF8F53E03CBE +F6D57B44F24CF821014C064278FD51B3427593D17694B4ABCE81F49CBB984C5878CDF0C38D1ED7FD +99B0B9A3BD8D8FF6219588B3B8FA59D0CDD1D9B2F65122AB45E48F1757467B9204926140E3C350C5 +A927A2E700173053EC35D3F1DA2D7258714C97FAA857F0898917BD94625C6D1E2D77138EFCAAAF51 +7B17FE187A2212C24A881A2C6A647DEF6376ED80AE4175C5EE80921F001995B44E49F0D33DD9075A +CF33BB03671C0BCC34AD5784AD1CDFED3A6D9BA103B3DDC1CC2DE74DBB576A0277715275218CD19C +A8899209125266D8BF1286F881DCC2C383749D1E768D670F4099F7DE959EDFE852583183C9111601 +2881A56A24AAF020EA45CD5F39660DEBCE30AC1C7B8CFC60387B1B0C3E361BE612FDFA9F01B7E4B4 +A18839A2C7E0E393EBC5AD9A8A4EBC316A740C1C295D9EF5F4DFFA0667F9582C0BB837B142C4CFC6 +B1798E9476D0631111033B8BA75A10FDC800E2AB1E0E829632F869CFE4737BE9E2800759EE0831DC +7D1195EAF80555771981DD6DC6606812D92CB8EF86447F5F6C6F626D0E265C67E52A6319189EE349 +D48E49DFE6A9E98F76C414A1E3217AE0A215A17E54AA498F4ECDC50242ACC7E2322F63BB2FF2189D +057E7354E32A3ED1803116176B9B9D0129930F919E2FEC280B2C8924E49E7BB75768A2EE1DA8ADBE +D4E3589906DF1B923AEF84C1BD327438B731012E69BB0D43A1842CB88BB54EA4516477F704CFEB28 +6E3EA483445AD4D74586FCF32E96D366901084365F693A53C5FB532FBFE7BC0CADC404C4985042D6 +8DBB90A6DCDA3531EE324D558A214F935CD9FCC9A0CEBE9B5FB0323F4B3820529599EF48EE068B5A +CE85004FEA2984F0A86F5AC9D56163BBFE1142B774148F1EB0A4DC89C3349052533A7DE66729DB24 +41B82F8F7360111DACF69293C9B281A0534F3E9E9224A75C49A832F28B2E497262475507B6DDFA9F +01CA0A6696E3F5AC7EA68595EBA0C2EB8A47813FF936D84AC1B23ECA7AA2862B793CCBB0DF9FDD49 +31BEF354CEC12FBF478559FEC29F81ADF4452E83963E56541D31F3691C93A50F0BBA5E9552C4F2A2 +3A6E53060729854A3DD71CC4308B91957DB19E66AAA18FA67055A950F1C2CFF78A03BC1A588CF624 +696068068719AFB1001C4581EE072113882D9052B21E355D401ED8CD24D067B99E616BDA5A0A5A93 +36FC499632B79FF2FD0DEFB096EF46B75E2D4E0F48DAEA239719FEC4D9A29818F5875FC5041A9EDB +D26CAF0ACE14CC80BA49BBA59E918EB3D8F1E541AA16026585A2F72DF7D83541816DE46981FB3EFD +0C30E458CFAD04C79421AB7C4925E23AEA07F9F018431C790002596D26BD9663B51B699DF53E4882 +CBC34EDE88EB55045B889B6062E35FD1E018BCE785157B85EC3B9CA6C85D4B16238275385B8285DB +012D8FB7C9F5B946A41D7A0FB878FF72C39683144D8A007CFF631B43748F2D5FC690300F9BC0C837 +006B92ECEBE0605E8C3A4A400E18AE8997D1B45FEE10068E247C647CF82C6DFBE5E881D511FFA687 +B7AEB78546BFD07D5F7EC242DCEF4930D8AAAD8C6152B6642AAC325963FD147F236BB850A9966573 +9D06CDBD7CA79A527DCF461E33F22BC9C5DB00DA2BD3DDDD8C99D99793BC98282AA8872FF96C3942 +85D82D9419EB78B6AE37A5F519397700F75D624A09BD255B576E955A323E784E8FC31131F003B0E3 +024A4F58FEF2A6C043796201FC425482E1155E229D1B2D43EF7B0D22322B22EF5C9A1BE026A1C3D3 +75EDAFF99597E1E5477952A4E8D2ACF5D014BC00DC2A272FA62B6983E27D228881E2EF2B8B95A681 +CBE90C5FDE16331C85222FE2A16F0A3C3000A63E2E21666C0C119F8AF89A543D37977069A5ACF155 +6324F05204CE8CAD50FF4FB630D9CBBFC324DEDA584AA56A99D3A76FF55BDC2C2EA3A021361CCD4A +83C7A5E2768D210FA6DE889FD48A39D679C94EC3C99A8D33FF11377DA7F6F1B71A2A05B302ECDE95 +4F26773F39AC881542F0D0969C3995C3519A8EF70B4220D86BF01BEECC6462855E7B686E1AFF1CA9 +1FB8FD8B4A69E10EE0C2AD94ADD44449506F9B6EF43641F2026EFF6E605C670560C2B74706FB949A +A7E8CC6A2D0D6207E457E7FD87EC1B9092DC68B9143947CC8ED14AFDDCBF8FDDA228A76847F96802 +E561F67CEEFDE45AE587673983FC04C96744DBAA83F2DC838D633943C75DCB9E6410474EB27B348F +26E505F0AB90878940E846C5E9F3C5FE8C3558C3236B1B88C405716949B8506841CABE1717474BB7 +C30DB91CDEE33B0F844811762FAEC535BDCF84C1C747CEF9B1FA61D2AFB5A81335BC42C06A94D7D5 +9B7EDE55BCF6F9867AEE107555CDD084B7684C2C87087475A39A9DA6347BE281CE5635A4D07865BA +98CE26C1465B1AB0343F49FF37B4D0CA9F3BB693D78DC3B21925CB996A038DCC172527FE57C07460 +EF39C07D4396E7FA970D9F22ABD21A9C794B64AD96762C7428F59A8757C36D6C4FFB23216195A04C +2A2C2E7B10EF7193931544D782FEE4B91E01119C5553BBC6252270A8D8C56DD62D448F5AD8DC69CC +B45E1F17F0AA1E445129DD00F000005B23D38DE93A3BE55A4C041947F36B4E4536E307D0180553F9 +2E46B743881CB5D5386C48C7D5F84C2BCD06B9C501F78C7EE61FA23516791FCF4DB278AF688A2E60 +10A56692AD92008497487EDFE4BD5FA083FA544138B20D6940020887E35D46E093B71F7A04A67460 +DC8116B4D4839625D7CA6959D6831CD93F81AC4EA2709036DD738364FDE71113BF22EBF13DFE1642 +E564701E6F0FFE7511EDF03FE448C2B28C64FB7D54B94CA576E481FA56B2B18AF10C71F699B6BFD4 +7459CDE1869D0FD306BF489A6F42E5B2F05CCF55BB6B9526973D19CB134CA7F13F1DB3716F8CC217 +73A832568C16250B5CDB16DF24BF81D49F5B37018BD310262EA7078107868AB0216CEC83CEFCAB1E +9F2C665A31585CA04DC01879CAA79AAA5AB201B516F7052B01B16BEE5606098393B0E5D9F9E5E3F4 +EB20F63C958E796DF41CF28839F5C62A0431648745D7837B519F3AA36BC6C08EF040CCF53D9B6D8C +0C7D1A84D707EC57A3C6AC9A62AB37251A01A5ED40FDEC6F5BE6E34C6A91D058319439778A2EE5D0 +363E2E1F33463C33327D05FFC0CBF08D5BC457C7230448972FB9B4D0D782BA7DBF10D3FFEF8BF523 +6EC16D4DD6D0D870D9D5EB5C64C9A46A4F583D4F831FEE74B0E5B33A09ABFD4444929BD8F638CD72 +EAB99CF2E9551DF427683964A592E49D186F285258C5D5F62196A98532421D73E3495F82695FEEC6 +E1952C562D546B28618FFAEEBEFF03A57F4D855021F85B0C7BC37FCC6DA9AECA099B646B99D41896 +09D3FF2D56422F8C37E97640293EC7C90E3380887836F4938FBF495CAC14FBA5648D89282D8D49D9 +1AF73ED36581139D8BD42551E263E830EA3C6EB381D85C42D74C50DB0CCAEC03F535ADE92128A016 +0E811C34748309AF7604919B66CD43EB5CA975302DCB6076FEB6BDD6FF55976FE990FB0CE9ABB11B +195403FB26E3D6C6A0DE1C5BE79E171A61E21F79EE8DBE7A832519813EF6B33EA098C2C32ADEA219 +AB2AAC8B093F40000995539D1276D5F2EF84CCD099B71FE4269BDBDB6A8D59C86F7D2E3FBCCF8773 +D0FAE97640BC1AD43CB4B992BFADFB09DBD0CAAEB8CD9DA264187C4F97300E9A6C9DEED5525479E6 +05C65AE336CBBDF4E5D7F79AD098F977285E065579B748FEAA97F2A753E1F962FCAB68D72BAA8EE4 +FF6691C23E31BC0F3E981A96FB440404856AE1AB32A7205B17D411D8F21C8C93B704D07EC594422A +BC368CDA2B1610CE6A973F4474E12B78B532666797F5755D269772C9F5400B3BFC6C58395D38527E +2CCCF29B56123F7DCEF3BDE5DC1DFC5B0293BB125085B1D2D929BC3EE84F4FAD571A4991C3DEE03F +2DB3A3097E52B1A7D5C73CCB6148EAC62E8E36DE9A71C57638C6E4D5D9DED18174E8C390E50B4A5B +913C074EEAEBE390B214B3A68F02862B9A296DB4B409769649E51D738CBBDFB7702E15C73C2AFC6B +C37CE15171F4E822CF20EFE55D9F061AA43E648989628FF79E65932390CBB15D8E621333B18B11C3 +BDF96F841D7434E01AD501FEA964A75B248A35CD9DF9A37E48A1E5A09C624B93CE44F0042FA00D7F +9EE89B9F7AB785E9C718CF6E7228F743271C2C9BBA17E5208B920E44E765D99D86650EB454B0FAAA +112753AA1BD3A24239E9C5FC47EEB1547AC9D23731B8DC48B9707830DAEC60C8D3790BBA1120F776 +4EFAC542CFFBCD5C05F9510B27B2534B704ECD36C8B041FD49A96881302FFF5B0163A2DD09C751D6 +D6AFEA9170A4F4C4AB8D46E62F763FE1BDA51DD1CE4A27E772F3A2869155F762FF26B7AA6FCFA4F1 +292E56F03AAB6322BF867E7710C34D43B5D85B45AA68014AD7879EED051B1933E491496E3E26D9AA +8B80A07BF2B94F1077E84A9726F08199887D66DE7A307BF33C30DD9CF3DA188088C03B2BAD09A217 +6B110DB2C868B53DA9A66C85737BA66C93C58A259860E294AD0191E3A72C73F40B0BD98699AA08DA +F03587B78F391F3A4313C58D9F29B53C70785637BD0C58310109C54091AB0A34CBB0C478613A7AC0 +FB8F0A8B4645AC966395D8BA775262CD291136AFFDDF01C1D83DD4EB3B59CCAD18057FE7D92A8CD4 +A58F22508D9FD7CF356571F701BBB23E749BDDCBF8A317FDA0AEFD952BB18545610FFAD3AC143D35 +1B8DB3F66293375E0E50235F0D0466932181D377EDD32A5F0FFA4E22B5A0CB4F343D9A7E4A342E9D +09DFF6C697630CD3971802C277A5590B8CA94BDE6B38446C794D072BBCCB724D5BC208EEF1B018D7 +39373BB910D668882CAA779C2D686081DE6A2606417B54D7C20E0E7F722648D893E4EDBAE8F00D6A +6DA3712F91AE860C756D1127D133AB828E9D80023B50B162C5A1C5CDF70CCB3FDD7EA060ED20838B +E1E50C4094C9E79E1A0187CDF780CAF45A725964F004253E034C5BE46BBF89D94631F1A33BAA35B8 +4FA2A9D08481C6674126CD96ED05DCE48BDA069D902D6836D5DFBA701DC0F98A863E64F0E312145D +8DC0B77F25B43AEC729A1243B45B08CA228DD6101CAA2AC5ADCC8EFF84A4CA3F254176C2CC711EE6 +C273835D0FD3528ECA2A976B88E51FE347FDB60F32370B66D338931D6581630ED586F349C638960C +31AE4204E89521A96E1219E696B913DEB2AAB7A3B022D06F34FDFCB810A04E60A4FEBE284C2F063E +0AE9EDF87704921CCFA193BDC912B747E13570066223A49F1F6E2AF0D4D65DA04CA876FF7A462FFC +9C0BA2CC545C3BD36DBE762F32B2D6BE5867C59F479195C92440DC165098B74EA5C3AD93CDF2D410 +B04C16BC7801E7956F4E5107450787AA592493171C3628E6B8F49D4F8429EB98DC52EF025F001387 +BC1A7093F7A99F10B5D2D7DD8BBB393BF6E56F08F4F7FA1A343F220D5A1EAE7168C74D41BE1DC1A8 +3BD65B72B982F4F7B34F24F97F9EC9A91011064031FACFF2A14921A32024385F4E061CD07D152E74 +1BF97156D951A342488FA7F5EF934CCAD13E2753A0AB7A1F565C2F7F6B349DF03BBC25BBD972A9AD +F809BB5C5048A8CCEF9297B2ED3324D18867F293CC66E88B3A39D107B610DFE79A3B4E83A96D3D52 +A17FE8A62C9FDD271130148366942C9CE57558D023DA5F7501319EBFA33DE9E6D1E76D7C20DB8A09 +B657839DA99F3D8143F1EE6253A3295C9651FA4366547893C2DC7ABCBF4BB7609DE5D001E0A36D9F +FBE01F7D0903B3208AE8547E2E5F14EC1AF4C2535CA8F4EA37E3F3CE172C7A1E8308995B1CC23E6E +81190246BCAB6E755BF868D449BB02A2AA87C44C9CC0F571ADC72547CEECBE104BB274B8AC16DCB7 +5D5F458D356466B921ACDEEAE384E2EB1DF6EF393B41B9747F0A4FAEB4AF1928D9AD6FB7E06FDC62 +1E4C6FC98CFB43F88584BD55D9B97CC9549093EDE586912161931162B1B1D52D0443260DABA02AF2 +B4432100D5506546013DA703573FA8013685CC798CE501960093DED713FFCCF89CA2B9106390198C +29A00864108CDCC1984A8BAB53919028C01B26ECC7925E38CBE6CCA8978EE21C2B06E7B3E48FBA97 +8E2A7D186E563C088F84AA23178B60E4729EE87D67B1091F3B6973676C1CBFE6530EB773C62E2C24 +97014AB0E8B71A1F4E86A378AA26591511BEE3CF3D64C94848582E1354E1605B6457823F2C5E640A +D3802946BB2E7E8E594E8C04B430C2385DD40746CE8534F50842E74D7115F3DB0C72D1C9C607C657 +3B094AEB73B7A79876CFFC3E2F8C9FEAAA07D3BFCE05B61F7749A8793BE90CCCECA2D7077F25E899 +D3331FE161A7E86C842495D584C6E4A0880B2951D8A13B88C4672080A0B1BE36BF47C3ACE7288CFE +41A8C1BAA6F0814A947FBD6B3AA72B6C73A8C578CA51CCC96F2352316C467BB960E981F2B6485BFB +44B577E71EFDA16E7405954BC7C9F0759F5A9F1EBCD2FA9CC9648D5831A68887F41B15081A204C24 +B4B992A231DEF9E698D4C3A25B6F5474F5BE6A601F2D337A58A0D21FF37FD91EB86D1D738893A03A +69F0CD743F611CDFFE69DB2C6ED0E4611D56F803BB0DC06E7FE85A303839612707647B1BE9FAF8D6 +84122CA9E5CB8BDE2936D3F4FF254D31529D7538BBD4D35539489F9E7316F24214B996BCDCF1818E +749A71CF0E8845AA1E2A58AA62A48E02BA4564625D20AA220EE719608521D7D7A7FCA0BD8904A401 +9819D371F3F59D46C1354E5FC1A6E5F79B20CF4ACA2BF0F2DE73DA193A6F9ACBFE0B4731C4BCEBE6 +D96FE822965DE965232282A3A130361F188B3AABDA95A8A2790D9240BE008B6A6DE4BBFCADA05B67 +86B9BB8E0DFA0C30043A3B07ED46277E07B9808422C8ED16758B9C396F4EA929D769785B2C9568E5 +70A83B989B25CE200F1727D41E2B702E7F88F1784F4C83FA60A74EB26B2DA95126E508ED519A61CC +151DB6804F61826C5F86D8FA89D06E526FED97A0DB88EDB432FF32C1ACC9B622EEDF601081AF7B96 +3C9CFC1D13E4A9C74FEA0A1C8E3D8653CD92A944D4CA6B0D306619AFD503506D77732D6514F604BE +4610C2560931BDE0B40939BC1D126B0E97F72AE1B4A9252123B54F7A27E0CFA4425B4546526FD741 +CA77952B10D13E0AC2E32006A903808FF0CD013F936238C74CC75FD915244C56A8412F37F0134840 +347699508D6F3D7F3203A25B7C70100719582CD588590EE34B3AB13E255B613A6D00386A0104CC5E +D2C646F09A88888D3751651D5646C5227A3C80E8DA1B0A331121DD2429F1F4775D30564DFF47D01B +BE2C6C72CE4D1FD9A2077C04D2B0274B8916F6A9D1A4A6964A534F47CF241D5A8E34B23F85BE9ACF +FC2FEA961F277539F215F8728D6788F67BEAF45502839BCF23D8763C3949352F00C579A9A4FC408E +C625E310DAE61512DFE6844E82D36A2F81709E1F05B38AE9C222ED62C961EE63593CED7AAF73CE2E +D3667740C77B309B93EEFE1B4BA65D48575A66BE86743DC9E5D3C2FF418D11F7F211B86E827EE1DF +C3613E7498030F07050524536D1F8A94DDB6698BE7B963C55CB3F74B676CD815A7B3DF4B1A0EA2BE +1B0B9A11FFBFD5B1FA49668AEE14629316AF436A0821C20BEEF7B3480847934A99F6D85B68F4DDF8 +859A754E009428AF89A90D1852C220A607FF0806E8080726EDC94D691D214B4521C147C4273AEBDD +BB4A697EF16448CD9B2FC95293305858DECFD406B89B9F3FDAE2AC579E80CF321EBAE5701FB2F7CA +D8ED04B4A63115886D45D6120F69AEF1A21D80AD3C2D35D2899F1902242B96CD349E0AAADA40F7A1 +1282B6B52BDD97708E58DC5E2D22D1153E5FA3F3B300BCDFAF98DEC2F4E3C82A1C85F985735F3987 +4F557579F422664E07CBE19DA680EFB0FC82C323EC5C4644C51709AC8D674608A8043C91E6C7988D +430F10BA6CE1FC7FC0604FCD8F723895250AEC36CC35B3FA14FE2A0D24095DCC30B2093F2298F5F0 +A97676A0BE66C3DC9ADACFE2FC0F721A20E945AFC1096A619075D5E9A264C796EC6C90EF1AEEA8DC +089B44FFC13D27CB2370070A52D4416C53F364393E46EDD7EDE00799960CE6E0D57E4909E88ADD64 +BDD2B0EBE2D73FA6ACF8B40280DAA0637E705C65AABD523B8815F22F23E9FF81E7829C7E4BC980C9 +143AEBE1A04DC0D253396BBB7268BD5AEEA356B610D5DCEE03135E00AE34388251F31714A1C40E18 +2652C48CDA2211A22CB6F02490E69A44CECB169754C53B16028D352E0119F5D5FAE0BD7EA1CDA647 +12A6147374B64244E21E9EC9F0D1381AD22D5B6212B26C3F9AA5F6045F25DD9F5EB4489EA39B1945 +331AC70510C5752557DE21D0A6CFC1EB10A98FA867B76DA6E4249469F591FD154D39E89364A43DB0 +07AA0D7A911CFAE6CE2B557997FBC44F55A27F622BD7B8B10EC9F5D10F2649A646FD964AE1B111B3 +5B46A252C4DEE44E7426EB5739F24E8A390694597DB3A1FE7800C97E59558322F0E49A0CCE2AD94B +1E2D1026AFA771723E3F523916F55ED866C9FB4A2F759651C613A2CFF362028CDF9D38F05D4C7C60 +24C533E930B64B099FB1AF04B01F5FB9CA6867E6EFF55A772C5391831059987E10CBF987E3F378E0 +1329F73D54DC0484177D3C3C06F67397955FF1CA4EF8AD1606B70455255D631A7D6EB92BFDBA14A0 +FF28B2ACE7E81AD666EA9B3A0F5A6BA3B5DFE35044FA4B3D8ED956009C60E98CC132F2E84967F4A9 +8A67B336D5EE7CAF7DD1F74D1FA08619941361FA7312CF225D89CEF97E864C8369EAFAB94D97F056 +5505D825972B754F6729596EEA91210B75DD8F645382ACE36DE60819A02B3B48DD00F5485F9264F9 +FA926D732E2C267B0BE8CA98526F124F97EFDB86132C5EF16B103908172FC51F286FFE45FF253512 +E0033F037FF182BA536A9EB2DF2D1DB257D9C86C46E1B002FB32AC70CA9462E6EB48994752CEBCE3 +9F08ABD4F4B0889283E55500702185A841E328 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndResource +%%BeginResource: font NimbusMonL-ReguObli +%!PS-AdobeFont-1.0: NimbusMonL-ReguObli 1.05 +%%CreationDate: Wed Dec 22 1999 +% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development +% (URW)++,Copyright 1999 by (URW)++ Design & Development +% See the file PUBLIC (Aladdin Free Public License) for license conditions. +% As a special exception, permission is granted to include this font +% program in a Postscript or PDF file that consists of a document that +% contains text to be displayed or printed using this font, regardless +% of the conditions or license applying to the document itself. +12 dict begin +/FontInfo 10 dict dup begin +/version (1.05) readonly def +/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def +/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def +/FullName (Nimbus Mono L Regular Oblique) readonly def +/FamilyName (Nimbus Mono L) readonly def +/Weight (Regular) readonly def +/ItalicAngle -12.0 def +/isFixedPitch false def +/UnderlinePosition -100 def +/UnderlineThickness 50 def +end readonly def +/FontName /NimbusMonL-ReguObli def +/PaintType 0 def +/WMode 0 def +/FontBBox {-61 -237 774 811} readonly def +/FontType 1 def +/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def +/Encoding StandardEncoding def +/UniqueID 5020947 def +currentdict end +currentfile eexec +E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89 +699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641 +2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2 +5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF +9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A208511C6D0C255B9A5BB2FDEDB4D399C6CF1 +94FFAC236883767C0F68F4EF84EE696B677DE704EC3B097384F2E673A1F51692B7B260693738C211 +9F7D90FFDB21EB715FD5B8134FC87DBA320EE54C2CEC6A4D6BB350555EAFF2EC4F84365CCC0802DB +B3BD0E3F0D9F858647DD637725C2CAF9557FDF842A0DA6A0CA0F1B442EF8EE6CBF2B03858468A466 +AC5883CBBD3815B283343B39205803C02C917D06825C09E2BB14609FA32C28D720C0E14A4B12D4F1 +25FF6281FF324DA33A56FC49987AC7D3AA206540F8127273FFE9A3DACFFE2B1C269D3DB9A811578A +C7D532C2EFC18376F473FBB2B32EF642B19CDEC1D6DE83643723E3C6DFC87F97A7007B6081894BBC +45C955B7001EB36211B26AD7A3D07459CFB33F9C54A40A360CB802FD202C8E93D4DB888B325CE246 +D02D1220ABF55CE646DFB45F07CB848406E470362F80CE4C02D98DD845189877732744CC16C7F566 +9F77EF096EA55AFF98AA103EEAEFB971731EBF3782E6AB725D4E9E35B2968689E8007C038CF25B6A +E69451A4731E79AC22BD268F56942A233E52D71873E83E00A1874E04D3B22E72FB2D0671AF81C698 +53C389B51F4A257373AEBF4DE2DA1E4DA5E2CA88941F81EAE0E32D982064C8AFDD7A9A600D56D736 +05B9463C6240606B3361BAF22AF74EF89AC804A5793BD512DA2D13F4BB1B73EFCA1E621ED2A65D66 +5AAD0AD228B3B7E3D90DBDB6061E172B686E92355A7C7459D83199040A368B5697DDC3B81DDAD341 +6FF4405E1096B1240EDC18A0E9985CA55A0D697972BB11E9F1BC30765D6775BB68C69704BE200EEF +4E11B78ADDB6229D8FA49A6B1525ADADF17122C0FFF51A08AA7AED158724AC4352EBB91ED0C157E2 +4281BDC1FD610195F495E87062A8C38E0D046DA4067EE16E81BC5F87E583315B973184E474064482 +9B2A52E0D37E249BAB31988B906F891AC904D1BB8901F0673AECE60ACEDE97B8DB7935C6488ADE8D +FD898027424AA85A11A3DA494498B084133B857017A6D507D70A3421235486EB3CF7613C59139FD4 +DCB92EADC60BB6225D9CD0599779217BDAF4813A453989B2E56903F4DBB83D83DF4837C86BB4C3D3 +CCF98F07A23EBBF7AB5687C3E1E6792E40F92A7A466DE352294064537505EEF3F9C308C9EB94506D +B02CFAE289F10005A6E42D2DCE43731A7AE368564B2983038DAD6987F67062199018395BC0FCAF28 +7A2B040C71F7325FA1E9A9808979B2FEF19096B98B8A0A728EB98F2BA3D33B49E3C20BE992822C7A +1BCCA5B4E4D1099D456D8D7D83C57ECBA0FF21428024F7572A1470317CB8CBC8679A974E13D88C68 +1338C68C9AC9557F97784F4E1C8C2E61F26023ACF46232CBBDF3C0BCC5583B935FE9FA09A562129A +8927AE73988DB0F7E733C6561CA7C9716DCA9B88208A715166F2FAE6D5EFF289A9B2EDCE813403A4 +16F243F1B57EEDE7D81E10C2DA4065A3082BC92A38B2457368EEC9C3C17296CB09819E9E642D7365 +F9A6EF430FC7DD611EA5FDBDEDFA72634AB599EB666A5DC178B0A0BD1FAB042792115EF3B6222C12 +41DCE36CB38B738F68B1B3CB489FED9E53315553F3C5C3BBCE40451E47B7EA53FD3D3ABA6CE0AD22 +5DAEE734BDFA3BF1D81C1B42C6D856A05D0924E03F7627C5EB24D7FBEA3BD85716207F961B56803D +BE046E81ED5FDC378F9CA52C14FD8544CA7C539201BEE06487EBDC30FF3B28E8264EC7FD5DA7E080 +65B0A9147344CE28DA5182335875E9F8B2347A44E33DFAA167232A5C3E69E8C5B58B7C7216537827 +C936F5741B87FC68753EB0D4A466961D0050DB59DF3195BD3379F5647F8CFED35DA952D7CF2DED45 +EB442DBFE992711D22EB228BDDF36B8D7DBA27062D60D2271EA8E8412F4290B58F5BE26FF06F0559 +872F9DE4DEAABA015EAB4904BA1F509F6D517C6E897312DDD571D769BC474FD378AF4360E8B1F103 +AA75F48721B9E0BA589319E15D74AC0B03D730C3EF708C7C504787483F134EA6297097B46D2680FF +8AA50B7A255563C88D594B912F5574564A1371463674793E4834AF11D14C7991E7FDB3A6ABF8529E +1A4F10CAE79C60D37429579093DBD041ECAF03824DF9C007E96F45595A524B27EF8774A83AEEBD3A +7134AB4435C80944DEFF5C1CBA921B0A41B9651968581DA4834B3C0E6D4DE13C1E792FCEED26A72A +DC4D9E3903661D8803DDB58EB2B929CE31FC9F50A694116B00AC9F3EEF53FFDB1ACA3394BF111610 +38F39917B022394C75A0D467D64B89A44E5505DED7D9C6B8BA6BA098F140C9C00E09200EB4828356 +A2D6BE9EC1D5524B09C06D9C6FCB5E2808050A339B5E5FD4DD6C2035A48FE9674520901EDCAD107F +67AC8C8E508E6003011978D77ED225F361BC0F86A98B6120EEAFB73F7377DB1E7213E02D12C330F5 +492511B4DDE08558D75D5B8AA2D56A3111DCCD257EE96E3446EF1C76F000C8916C4CE261425ED9D1 +5B58CED128DAA6C1300466E7B152BCFB5E6FAAB2519B8A98F26B29F98133AF886A0AA7E586A090BD +A1DC6120DBB5640885C609A8BDADEEFE5DE0DA5B75A8A29E92515E86E7E66BB29581E5AFF8CB6551 +D8D1103DF60D558E7987E6F56126A13DB2C9A04886C655064E68A0A20D1B7DE24DAD22BBFEE1B7C3 +C208D4FD6A58DE78D6A0A6126EFDEE3B1A9713DEE94069A9F0A2B392A2F391C4C75327803B53F252 +CC9EF0323F84929BA4716C50385681FF5B4ED54929821594F9026B7C1297941B178C3F8A704CE097 +60533DBC6CF4B18AFBCBAD039ECB2EBDC7838A9410E7B227924BED7123944675A5DBCA388B710F8A +F6048B03DFB713F881EA0F3B191A5CD989EA150B979059C8AADE403855815D8F7980CE6288F47EAA +37C1097D33F13776F08779063C5217D7408D9835AACBE5C071EA40C9AE6DF685F4A9827B828815D8 +F3A672E73A418E5CB15684EB6C6FE0998A386E124D76620446907F993BE16FE5AFCEC681F585601E +18182EDCFD3024062A3082AF97E803C47D32229D0A24596CF7E03F18229FA631175699E2F0D60FC0 +9C4F1954C5D12D03BFB4395F0E5EB6C6877083807D91D93CA4177A6B5A8D2AA500131FCB670E7118 +73F8A3C77575EC93A3ACBA37EA117DB268CF10D04AD0F079484DB124F6DC14A50AD3B0294F7157D0 +837D8F9A6060FBCB385606066401708C041594E0396A0BE4B8B66FEA141CCE4BD29366A986ADB98D +9A6935C49C57F8CD415E93FF8AE0DF75E463E02AAC68DF064C1B789B685F84E15E512404E065A39E +9E8F5568A7D97671AE1602605FC7E4933975189837586FB1A55007FBB0E91382A629277C36A190BC +85AF49EF3F0F38D4ADD2B5DEE09916B79690EC83473C63E92CF617617A66DF472A49641DA10654E3 +AD3880D060B02A4A6C75B51E4E9917A2B6D8EFDA12D59DE5A8E222DC7E82F02F23A9D3DBF637154F +719B14114DBB102BE5EB76B441D7E9990EF6420C2E80942C8AED5A1D0B19BCE115B5929AB9E145F1 +496753DD6B1798324F5EC1D0C7F26FC3045D7BB46A14110C99BA07A45EC16002CB754C0BAE7A1A88 +EB387BB345FA70B0A38AB4D532C2DE49274D4F86F2582728A2CC54B4C09D26C0CDEB8FEE6A42885C +6207D74953CFCC583ED82DD7C0F29D35BDAE5BB251B8A2D4B1DC97E2264DCE035E359DFBADDE84F7 +37EA6A59C23D1A64D963E635769233624F7682EA34636B595CCD064AAFF3887D916867475731BFCB +F7F96D5E5E1FBE6AABF454C2F504EA4E8EB382911560195295C87793D5F7739AD7EC7176E126413C +D4D1058EBD7D6EBEE14BB94A1ECF28B686411D91E07373E891F78C4C0A05D2E8D90A8AE2614F7FC2 +63A762D0F43485473A54C31726F8547701D4A38D20565ED1707847AED9C805780F062B847E668E15 +565CBA07A72B0BA99F03FB57D26FA26FF579C30EED0AAB6FEC1B5DBEA81AA88F16F0C9BE869505BE +18C1CB79657D91D6706E2A3F0BE9920655B93EBBAE2B4D0B5DF6BE622C951F2CFA42AEDBF7AE649E +2150FE87CDBF5C2685EF36051080BF39D864573A45AE2648AD97662B1F69787031B9BC43511FB841 +55ECDC3D91E2475D072BDE6A5207ACEA1E0D2ECB1DA8A1BC4BEEC335A5C7102963E84B97BE741C44 +58ACC3D72A7E53B1F08C955F33EDC3A0DC3E7308270C0F7FF814B111459985733C62E8863625A551 +837952F3CBF32ADCFD9F345E14B585B23ECC440775310654DAF7F41E56FF45F89701292019A94BF3 +0EB2D65E14B1A1D6BF89D4CC43187ADADF3F6E03A90ED01E5D876BD3AA56E5EE84DBAA4DAD9824DE +9984BD45AF96FB8A56C010B3C3A3C6139D58E9D69D9109DB18561B55EAD6452497840B9AE90C749C +155B6329716F0152A7AD52DBD0B8A25B9995E1416681F38FDBDFA443879B5C4C25AA29E0DCC07DE8 +BB161C36D76EF286EC88D57C74BF44DBCB4FEFF771D3BD82C8F4E233357C48E516EFE3DB9E60EF16 +8E2C45B54651DF9A5ACB5F1790F7929BCB16CE5E9F6A43919AD287DBC8E12D9F9E97E5DBAA592879 +1A5A02D39D259F3CE273A870906A643CC18D86E23F115D2A35DE6926053D8C84B940B362E7DB183C +4905060316B269223DAD309EB5AC96DEBA757BEA45FA3100F77F4765334EDF3D659E09BD1A5552DA +492BE9174DD406F8353A059ECFEE3709422940A8C369919EE1F22F7C02412C995FE93DC4559D32A3 +155DD22D3526D89B16D9ADDC30CB7ADA6E52D62C5F2DFD142D4D7B6E066671EBAD08F54917E31704 +1F410CFD8A3243F8B39459C418B7B7C6494551C6F6753A94072D09E0D812351D62916383C6E061F3 +5ED864923002007E626089772D269B298DCA2CC1F25D9BE43FD8AD62D554C16AFEB7EF6E5DDA66D0 +5A810F003CDDCFD2C02FFF02BB61344968091F67D3862C1499409ECCA137B9A2A9BE314995B818AC +CDAE27ED4AD583BE29DDE4E8C2400C5F8152C85709AD2A4737BAC768FEB70CE81A92C9657DDDB2D0 +BCF9169D272A063C75C150ADDFCBC2F5F2503DE3D13231AA8CFB396DB38E80197A605F6BC20EFA1E +DE40CF424CF221218D51BEACE64A3DC88377E4F3EFE43DB4F4FC0803BF61764104CFF0B618C90311 +98B094E20B0FACFB94240B438B67BA298E31D3F4E31FD190E48BFCE27B1BE29D36E765E7D295E96E +DCE09094FAC43B87E294818FDE9363FC7DC5EA36A1497EE25762D02DFA00A9BE53F87ABE62E52ED6 +F59818FDFCA643042EC13D670DED1980413950EE43372D31AE2694B83DDA42E1FBB049F7E7B7E69C +93FFA3195A2462423DD2C022E5141783FFA07E192AEBC5070F08B23AEC9142EED56DA74F93BDB504 +78DA55DDD0A9987FEA131E4CCA0EFC51064E4B37632728261369C3FEDACA100F1AA78FB718ECE7A9 +F56296C5FB43781E63F36B0E1D34BB748EFF35E1953941F94D1A9B0FA474FD68B47183F2AC53A63F +9F1D30B9B89C5FE54C3765B43DB403D57994701C133E42B950D9BB1CA202F15B5E590EE75598FAE4 +3D5CF1546572770BBA9A6373F100CDC61DB4E5EBBE0A93E0E51C86005E333F69110B1C8E492F2BF2 +52CADD5B73E7D3EBB53E759353F1EF3C9B8B39C230D13AB7158A5D92EE4C452F81F6DFC18803280A +A023832FD0DCB482CE5AF615C952BC3F7E58F6417D69775FC7C0D5B405AAC632857736ACF32B2EE0 +F2A2C0F3B3CAD483C614505BE94706322F2A2830FC5AB592907D0291ED1873377E7A6158140C2CDB +1B0E27EEC9CA50176102200992308045CCB5A169B61EA0546778B8D280737319046716604945A21F +2A1CB9E15E3A5DB31E0FB5A3B0AFDFDF6F3424B7536D473F9756CA3694DEE4301FB1AB1AE47128F8 +D2B461C051C1B999DBB010E78DD13AFCBBA6F7D5226D540527F17881A18F551B3EEF76A7E28B4FDD +879381A2217EF2FF9F9982E9EA70AD2003B862D7C36D57C5FF9FBEAAB56040FEE973EFC3B34D8319 +1960010110BA10694C17B7635AE03CC1CD087C0B05522A7A791F0CA34022A3F5860B536D9551BDFD +BF560A07F63AA4E687407E5E48584E689591F1B52671213E430A708C06A34D2E1D51CFA6B328A122 +007C81B5EB263B967746961BCFC8772F8502DD95898724ABF369B0877F3313A167F3F714023C229C +5757D4D46FCD9B4AFECD093DCABE52B78132CE9AB6225C9A344C4BF8D96F2C50C4272CB9AA0D606F +013B2642F8C880E08EA2822C8CF5097D2CDB64932FE195ABD5FDF36D3BE123AEDD8BA2F82A8A628D +BE3ED6129DC0FDC4BE50D5574AE4FECC65062E70F4703BFECB35EADE196294FE173EA57938679DBA +6D15448FF44C0D1A903B202439DA93C0B0E612110068F8079219AA89F435E44D0464F54833BEB338 +670BD820D941DF4B31F51B895BEDF833F9C43CB7616DB80F988CE72FD3C12C7D49F740CF85B4766C +0ED398EB837695D102DEC16E24B7475A0F5DDE88FBF2D6B94F126417C811E8362B9CCC52D8891C13 +C10937AACC228D621D4712CB9DE0BAB60EDE2A97E9292BE04E42E6D3425594DF56931A61E1F96172 +6AF6E6891D63B240E6E79E5BF30C052091D681BA1102409874CFD8EDC3EE2BE331676E31AC00F807 +91D1019BB789CA4F5907F4823B002AF3581448C352BB67D80FDFFCD1C5BEEF60523330AA2C045600 +8F62DEB55E69AC2F86369FAB1ECC90D2487954E61117A90D9269A65DFBDF297EBD29C3DD1F62755F +8F289C42A534F59650685F8576EA2FC5D26B99B8E3DCD3F1FEEC73131000F99AA9868EA9BAC0B56D +AE2CF46DA6CC1D18C0AB8D77BECFF7B89992175CBA2E22779C13DB9DF53FF5B1C8FE95E164997D94 +202C37175E562C8622989B075CDCDE173452C064274354D5DB8F7D5A78D48AD4A103B9E47500D08E +DC7C51C1F3CFA7F43C3686A3C24A7EB5018B0F419961564F87E212CE0A0741AC68D6822C7AB9FD68 +85F5D0B2AC249CB7F50E2353CC4B0A6A24562F564FBBC7090C3FDF1284AB0EC615E0B3FBE132F315 +70C8A65C814F93910AA4BB80D516CB70D2E1D11969238E6F022D628FA2F33A0A15C4EF0CE7F753DF +80A8AD9494885A1B9ADAE6C38AC9DA6FB0A61696AD3A502630252AD7B574C841117D34BD20BD6581 +217D977B35F5D04E02B933E1E84F5C090F6615AF484D63265D28517BA74BEA8876FDA332A84AEA12 +E6CD82B94AE10A778CD3A216ABC08495EF319F06AD6FF8ADD237D911F846A514FDBFAA8A1EC8E0AA +9F80F11F1CE615519A4B044F3D1CF1A17D7F3D2174222A5FFA8B39F20197FF6CAF250B6ADBDBF519 +1C525070C8D38220FB501C223F493D80F498621A02EBCCD6EFE914F16B2A435D60C0A1A453E288A5 +3D818FE1EDCA7D55A26A017F2EE47A816E90D6C3FCDF0035EEA307DFB06D2BCCE43458A67354A4ED +B6E5C57233DE4FBE41ED07EE5EC77A5DFADC4032138DA9E1B74428CAD02A913E40152F8063A774D4 +FDD4070E4B8A6C089F199AF7C529C277E902195DB760D81EC655DFFD1BB283F3C5AA8BB58F2476BC +797B2892E94414ABBE96D4DB93E280CF7DE23EB852E7CA954D6682A6F1A4BE0507884C2A05AC863D +2BA73F3B54668397B6C54DC2F4183130AB414875F3C3D8792BF7E5FC4D228DF87748BF0B14178DB7 +E3FFB7891D700A1E9520D778B095DA80E4801F53442D5C073EDEB706A5DB8466FFE7E701ABA9C364 +A37169F585C883A83713A61C9C3BD9336A667EA4E3DB5F4DF6BC6A552BE8D3EF093639EC67E5FF71 +8959F9902477F5AA894ED2D1CD312ED82EE417D95C49C96671B23FB0E1738E892ADFFE62EC1C3D4C +BEB6CD089C98DE8D247DF7ED17DFA2959D3662F105E8386D75AD308480536959F8E6CF8F2C6937B0 +9F2E8137C811327D6B165ABE46C51834A955FE8306D10033F8C2A34667F13A8BA831CCF52C7A21C1 +3DB92F3E77B55CE291F6190BB1D194A33FD73151C3F61ABD2D8A0C9BDE90E796BD996D2D0094DB2B +E98657E751BDEEFE8A43EE4501B98F0CC6D80805189438872A60047A8CAA9039893530A3E5F6BD75 +BB466B25165737C939AFF3EA59BFF4A7DB09C2A5B36B8A1F0C6C5E5870C7C9412589877EF44F8428 +4B8A53B5B74315CE72D2EAFC631BC4CC2E5B71DC958B5A6350CB5F615C3A4502E973622E3E18193B +69572DEF1D02303A375ED60ABA1BC8A179FAA0F221A49078FE15AE13383585FB45FF4D5F3BB3D0F6 +D8BF62E9BD6BAB3C9A7D38C8A5AB0BE57ACDADCBD02B1DC7952D73AEF702D406F62719922BEA96B8 +FDC9B879708E794891C7A0A42F2CCD6812C3F4DB030B5178E3A627C3E77621D312CE4EBE815CD387 +7208FAD92761A5396B67E835222609F823728B1C987857CFEAAE21F2AD5EA9D841212993508091A4 +A2C268BF1D8DA1C650F6AB93995E7C13A3F84DB55748C626FD09C0DA1E3325CCB0BF091E996245BF +51EB486680162BAE63B6513C74CE83B92359938439921950D713C69324A87BCE67B45A030C9CF10A +DFA0A82781D49FF224AC57A23C6CB321F95915C5E14E41FA852F66E1E2044A9E7B1DC3BE9E818515 +D28B2C4D2F2210098C39557067062BA4239F2AAE28816D999955910298A450741947A9A1AABCBD8A +FF3530626089978C87DFC73618C044731B6DB8007739A9699ABC354A6F985E03C11D750B8B9E9AE0 +5436205FAAD1B895B159E2C90562B82A62EA1A7FFB501767DCE2B11C51D55A17529EF5ADF0A0EE9A +96D0E7E89F68E50EED813836531B4B46E9071E84AA413F4135CC882CE832BF78ECFA7CAB0C9F64EB +92C86DFCD1152BB7D4AB33831AA0C139B555967F6346068D5C3351A7A4368EEBD2933E6B9F789DAF +37EF536FCF965C397AF1B7F98AF864B301F3F440B7ACF704B59540453678FD6C1504519481893812 +3E2F47B265EC4F5CF2172D394543D84CD4281165CBEB11349B315A85DEB2D1699507B0C8C110C726 +62EA2959C4962FF093AA5EE6F21F89B3CCB0149CEFEF1855B9A48D28BB363416C015A1F4EA1975C3 +D8807F616C5817C8162536176F464A198EBEE6C97029F15F414275A39B8219128B8C8542E9483550 +7FC2D3908BB0EC375771280B9EBE87E827811418EF93E52EF70546891BFC0FB34969FD7DEA4CE752 +4D9EEFF2B46BED908C0FB2E02EFC1D1624642EAEA1CAC1EB4841E020532E88E59AC890E6C3F44734 +B99722E9816402D1D0FDF8045C5481EC055100836EBFB48E9FBC392143032C909853C9BA38A19363 +141BED09DAF02FDF4E7CC9808321CD0708A1B45270BFFCC3A0D7C27F7E781713D5DECE82C72ED303 +86B02D14575A1A6447547ECC7FAAC1BDFF332C92984758E242256C054656CDD2C45D46E67AEC6F83 +9F95D74E222A6EAE12EFAAB723A7C816D4E42D4ED2725A794743F67597F3DB8CCDDE45BAABC25726 +B851E02E56341EBE69E4D91F2A233583EC816F18A1DECBDA4AB69320F55E730617360FCFB8AC2D2B +737675B406297F7F8C4BC370CB084C22BFEC5FEF02E9AB290282F7B153F0A4B1AE569F1E52371A43 +46A748DDE09336CAD1F5337FC3D7CF0677091E59480AB15021E023E356B0E1BAC6C6471AD53625C7 +0206C338536F4D0D40733AB217E2297F86B593717C61458B6C93A16027CC886A8CFDC01EF19C34C9 +A608B95A84B6A2E31454BC03C10FA55CDCB7B1EB7DC16AC1E93981A46DECD7E7F00638DCAC568744 +69A2D9B45CBC81398727E4ED3DB5DB31965F358D8179CBF934EE2C4D652C9CC211807F070C80E3A8 +222B4C31FFEC8DFB9EE07A94C973462254BC1B1581903EE6F9AD91524A787129A63FCE048B45BBE6 +855826750C586B6B23B805FEC3E7AAAC079576949A06F422FC2C826BDB78AE96135E9E2C20C2B2EF +F6171D610B2EB8635ACAB7C5C5ED9C9FFC26CD54D2FD4CB9E4294E178CECA1E16CC8E3FC06518BD1 +6F4D63AE2B435753538834CDD9D8AE7DE624006CE688938031336351A6578C304C2E5480A3FCB43A +8BEE4953DABC30558B7790C6E7A6F0F9FFA557C50417407AC6A0DDA1E736F7070BC89455FC293453 +3DB004AA9070734C8C2608A07330E421A0220DAB99F8A77489132F6413ADB9EA637F3B75948050E6 +67276A55BEB09D4153DC126BBDBE0DB9298AC799A943D72AFB769BFA1488D311BEB86A907EC9385A +AE4F77835DFFE4389E3D9ADED1B08BBC2B1ED6084B3D1074A326CCBF38E06BD026919107BD03BD9C +30470DB779508DFE0DC82DFFD2DED749E872EB7EB9DDF509D5319865070DD76846C34E4E43691AF4 +29AA40DB4BF2CDD50B275589987D8081F7C5A0461AA5D1455A660178A94A0BA0DCB69C3CEBF5EE04 +26D6534F6F919D9795AD6A0E1A1F452AF3B4CB2EA54D6011FA809132421D111EFC51174E223AB6A1 +3596411A9723079231B050CEDAE7659CF168C39AEA9C6902C2CD37D25492CEE00096EDD63DC7643B +667FDFDE5B595DC54F0A72C2650E1E46990584C78A5CEF9BFC3C5F88CFB0C49CD6CADD9DBA675177 +D601927D75C6902B55AAED0E9E3CB52A577C887D581B3CE6201A1C77C9546CEE5A13B92963337F17 +070E2BF9F5C5E86B84225863874618AA50F4DE855DE567BF2AB7163944ED43DBD7F4BBC0E1623180 +7C43DCB47B2EB694E6FEDCFBE26194D2D9943A1BFE32AA1E5305F5E341EA021F91532162978DD1B8 +C5295A5E7551E2DEE46DC2347C6B32197AF430AF3BB676A53BCA9BD1EA88678377DC0A9A86E2AB6D +E29E3E261BFD5573C66FB5687BA9C0544D894A759866B066E1DB5C66E60AE071CC3A1C4AE40197CD +E4EC723F7B80137619DEDC99AF57A5497D6E03C1C9E672E74F48F6C213A3CFACF2699CAE72345A51 +C71C1D69348DE5BC5F443EC0EADE1E76A8A33066922CF3869E3C1D26A3B34E540DC08EA4DA2DDE3E +EB17C16790DA4EF1A3A76D71D34B788A87838BF2A5A3DB8176F9C097D2320050A79EA6C4A94926DA +11ABCDCD26DBA09FD33F30AEED977E8B5AD928F3967F607628859429DCB4ECEC7DA3411BE35A0385 +1017B535985632639D378CDCD13B00FE537A49FD9EB6DF1E3AAF5C41EBE35721FA6833C2FE08AA3C +FFC3477E7FCEBF9EF9F4DAE62FF78F319481C3F1E72999C8A493EC6EE295316B58A5CD62FFAB62C8 +96E521B678342F04BCE1613CF7F6778CBF5227BA20504500D743270771953ACBD5C6586432F3FA6C +0987BAD33B88BC6C15D29C4B3CC54A9DD72A2357AA5BAEB2CB057CDCE72DC80CC98C62B16AC50B4C +6A7641379B766CDDF990DBB2FC7F9CDBBA755B6E3DEA438FD6699C30A99A8B3178E6D613AA938120 +835E517431D28114BCA1AB745C11FE6E52ADB82B9D3D53A33BCC49740C93017D9531ECF43831359C +5C93CB0E926DB440B139E3125CC2E069B1CF6D96EF68407F32DB517242C3AE0BC6723E560B0F45FC +7F87A5E44E1751C8B7F9F669C24AD5CF16F84FB03BA121B86B0694234D8F2C9C947269AF96FCA08A +78F736E4E04ACEA44C5BAAFDE360FCD8BA6A59724CA86160A5527FD564468123D302DB45173C1B21 +6B01DC5B6D3415B13FBDBBD3121A5493374B3357EFB131CABFE5087AA1D2C7472B0377066B3632C8 +2073C6A846285CC953A8F28E131CF587B35217EE498D9A1DB57B063CE068DAF55D8CC1771C0C3099 +9CA4FDC5D67BE4E7E69418F6334BC6149000821B89A7437CCDF9A6A0ED702D5968F1E04F7E4FE9FE +C9D1E994885CB624035BBC5426CB8EDF0456828F8EEE75BE491B45FAC192A405EBA25CAA4F4C66C0 +DC234D7B417628DA5276C08260BE512B2432256C401A66E3B583E69D23E9FD278CD5F2178544D054 +16B9B4F61A88A4728AF2CEED07C08E207F31D644E8E3BA1E4E2F9D8E30936BCB9C6AEB54E37DB46B +D64F2ECC1021336D0564DF0F18E5A6B6BA470233D8D41FDD9D1079706EA685B6D8A740570BFB78E3 +984BB155C3155C69BCCCB41CB51975EEA1C1B4294CB546CFB03DC31BF86EC3BCB1977E8F94A771CA +B09DE12A82F1D6C791FA7800E5A21DF81C9C8FCDA78622ABE75B54AEEA747AA4F26D563200992E33 +7231A430137C720A17D44F3AD6CFFE63B2DE12D3184BD3E151F955786B8DDCCCB290C42718F3A219 +1759DF76371C2FC177544A6C425CAB14AAAB31628A9CF9D71B5257AFF0D59843989CF0D747375A26 +DC9ED29B66AC2147DA0168306C48C2484C70CA92F33C0C138F92F276F5EAF5EA3082A8A1CB12DB66 +1633C2F71E3B69918F509060AC949FCD52C36498A2ABB77D139DF1EB33E3B846A7C1BBDCEF5DEECA +4EF0AD250CEA9C2751E13EF7681E8FAE0491CFA6C144DBAC1FC39D39E76EB12D3EE9CA159AA77D27 +94F0C433345B135BA632F544082BBDC9471E9FA3AED3A7D465AB7158E8AC97F68B1FBC8D368E2350 +45C18EFCCADEE98778D894D96301F903283C5AE355A863BB0DC5809158F7E108662D04A5C1234915 +E7BD5B4C30F9EFA55E702E54F87FCA06FB321507BC57A1E55CC117E21AA4E3A4DFB77C1A949EFE36 +6D93F2BD827EF8CC16D387CA82AC039F77FE995BE6D9AEFC87F8D809E90C1017803BCFA1C737DAD5 +F1A631EBE6894AD20C70791665E7BC71F21C2C3F4462F60FDE75C8A377CF49BE99314663C6ECB538 +B1BF021B2F2174D2B22CF6FAD115EB0ECE8A2E64097A5FB0A2AF666E1EE13276AEC59FD0C9D4BFF2 +3F71E835984E5EEEE36490C54E077AD7355DBC98BDD37DF29B3DDF8C55480B7349C4D17322418705 +796A8C521FFF920DD11773FC44FC631C7D6E9B420D7965D7F62EC7385F2BE30A51E2D796483134F8 +40AEC71FA19ED1272C27F98F2CDC9C7E54DAB585AC1703ED08F5F9E825564902EFD08EDF99DFD494 +44C21FA6BE16CB8A1B6D0C8A5ABF80A50BB8D055483176FD0AA07EBAEAD88FD694F96FEBD60751E5 +C4D8F9BC747D4F4030BCDF9B0370B7A5E0A6923FF60DEA16EF47F886F10CCEE6956ECF41A21F7C59 +6F3BC78299A9657266807E01762B2B2878E551914CA312C2A68D34CD91E4F5115EA1FBE801346E14 +AE529049089B6B0273E258785773A9CE8E4B6C4211CB7C2767319576758F811CBAF3A3FFB41B3130 +6C49F3798B698A47BFA2E3CA0251C4D90C0B02ACA28C611744526906791D9E157E54CE4E1BCF5B68 +6990BA8AB7897D624EF00EAB92CBAC255AE9177DA9F0D86447D35B452CD2F337147B5D3EBBF2B952 +35778A72914EB3707EA78294B3A3BC4ACB19FE87C72AA1D982E4B822F07B115CADF4D3E7EE3D1BA7 +08653BEC6F0A352A0C33252ED0630E7274961896D461EE8BF523D5911BAC1C8AC763E5FB11FDD217 +4E1F129675969C195476C7A5E18A81BF9A11ED9F2336D5301E3BD32174ED5C933E8C85D6272EA218 +52A6F7E2AAB174E0965F73E0EF89E906BAFB181DBCF8B1F5AA0C12D12C6272753C016AFEC2EC9F95 +41B8757874D6F2E061ABBE8B29281677246305B3C41E90418426C575BAA216CEE3C5EC29B2FDEE1C +77C14FDF940792F48A56AE80AA33E370B037CB28A7373F882022AF378F26B6006A049FD3B35074A8 +65C97D153352ACC156992C00DE26AD21C982C71F0EDCFEB61593BB40FA5F2CEBF23C4FF34A4F4BDB +73CA273C269242D1C6117262B7C47771F2619FE5710855134A80FA8F92BB2425CF88940CA3450F81 +234ABF2B11775929B12CFF86442B2AA0F4243D324A5983E5D1829775B3C7A111D5622D1C4E2B2A2F +982FC8A95F789881416DCB34950A393F4F1720D2212F3D343A17683060182355DE9E4718506D76C9 +184F8DAC55788D7E603CFAF4907DDE965A49C323DFF425FE88C09AA4A4D16283F9B14AB9EF1BB885 +A954034710B4A9DA4C88A8A0932B18D139A687303EE562EC9F656F12F3E8F27DAA9C75DB0FA946FD +0E1A982BB58E040BFC0A49A4AD8CD668493FCB573C849EC5474049A693CBEBD4D79AC7515047CC34 +7A9A7570C90861F3ECFB57B9F53AB9C0D6B05C8C570A8F3C04D58555A45524C98FF091B8F8A422F2 +E0E9E5A7B7FF69F1CEFC13E42F1CA276BCD584516D266BA6838D5E9CA9E9854F50C7D92CAED61AAC +AF758A7C7BE59C3BAA82BF32B691ACA3E8EB171E08AD22C39FBE586A54E6E4DE2CD86B31138546BB +8DA5834B2C6E4838547A1B67E651964E43988C8036931088904BBB589CA901E7EBBC094C0DA81E09 +1915D9E46828AD8596FD0FCA39FF12A6C27A359337F973809E81B2E9E3D43B3146F2516667E607FF +EB9AC80FC95A7B7D4DED551FEE0F3561C70DB2D69ABA96673E39E3397F1C3F8FE5F48BAB8AD6E0ED +8901F90F6CFF24E80CB5DCAC498506C4D01033E497C1241E413B022227A3264DA68BC3F91B35781F +A2D018475C199F43CBA7D3A0D5697B45321BAD2C394B207136E1E16B41794975E8903EF2B2E1C33F +87CF72C325C11EC0B92FD3890ACDF60B521DA32596763BDFCDCA837ADC6F26F129B23CA32F9CD39B +33E64576970DF3C05B8DCA4BFE2F17E6C5678B84D69494F1DBA9FE0446AE6AFEAA1FF245C07916C7 +B7569E6267C42B459435A1D116CEC665B311E404171774C0ACC8DDE96B0D9167C8CC7D99C4240559 +2D745C4428755500EB4719340D2FC6BC215B67823F69FA949C08B5EC985D7AA87C9AC1F9BCC8994C +6CBCE6027B7D1E0C22A83A5DE61DBA05D4AF6884C95F46BA7F253E0B2337E312916E163CAF9DB2EC +56C5425990FE73EE53E42B3BCCA1CF642F02B0C5ABD529B568E9ADFF865B9DC190240AD78AD226ED +884BED3C285B4CB0E3929E805C67F1318D186504D92085764B70DE6AB5AB6990F181BDA50FC31262 +348D980EC76608CF08176C2502E065AC2D8EA5CF9E2D44E2B70A7DDC7B922047C471DF8A0B2087D1 +106B5BD8A830EC0E53223CE3C96EF56E5541191167860EEA58D696EC357EC55799438C90156BBF2B +13A0D5C9EE93227746654ED73EA5B9CAB61DAC5BC690F89C87FECAF9AD03BD39E438F43B81D39E07 +E0422F94E8B096AB38C88BC2E1A043811D8141C1A35DD3A6DBE41620E83C8ED3A379CD80D4F9BC30 +41BB44B933DACA7C5D4427AE94A176829F24B5968B713431CB8BD9F53080832C6B784CEA9B515687 +F121983EB9D9C9CE8BD4FA3BEC48AFE64E643B7BD86D8383D07521FE5D091392BE124CCC91113604 +3824B686988E7C83AEBF406D2DA88FD952D0FA9327F4AD04C55FEDBFBFA76ECAE8A176C516479AE1 +467125B7EB3C9E7C5B103BC0C470946346DF271F8EE19DF7E3FF7478C35EE059297F4BF21A5C7B95 +993BE6202E897776952A7ED0613A5CACAFA731FFC633CAB62963150E86EDAC796026CE02EB235B9F +7A54E0B0C5281567138A612BAFE409A818C216DA8EAC5EDF9D1E3A1E3514AE50735A111B4D2AA083 +4EC6C11E290D58FF340F82F0E079F1C7B3566F2336EAA45BF72BCF88569988DB5F65D4C1E59B50F3 +41E45A899656A0B522847ED567B49CD5284FE50E5F8652CDAC1C076804F2B2185F6A51ED19DD4941 +2E65A0D2DBC844B75E2DF71B009776D9F97A4C6F786EFFEB87A307FB6B912BB659DC2BCC6D509A9F +BDE87DE8D716040A8551B6CCFB7743978AD992D14D2B85CA052E87326138DB196C24593F8F7ECD6F +486F85D1666B9DE2ACA6C7900044EE369D223524664A2790B773F9EA26E0A4CDFD709942A44298B8 +249506EB9B77BC887DC0EF947DDDC7CB3CFC6B48F060DBF032A11884E6C226D9D447A5A458CBA325 +D57E144C6DC295262763E7BB8FF6A0CA473EB7661C12E0E8E23EA37E8AB3387B9E54686F3E57765D +4067E521BC1AFAE52394227793C737C19208803F2F2DA920B553E2AAF94EB992AB17E31B58C15CC4 +AA8A1B444DF5B3E7CD937CF03E1F7FAC63342731B4589F16939D16E8E497A74CDE5686F529E9495E +1603D74875288CF53271DB9313A4511B104F80B179FCF213558970A002E945281BF3AE51E668DD6D +13D9E85152747F562CA0B75DDEC8FE9FE31F8D05B0F59E802888A7A4F19B29954A31108D2F041367 +DEBD6AA1CAD856BDD1427E9EFE89956FE28D500CDC6A0CB80A76902A08D0BC6705583243F1DD8020 +749B257EDF4803BCAA653F7FD6D8B91690995BA5EA3EE92FCD367C11601C6B8ADCEDCE67B16C596C +5D200693AC5FA15D4CC6CE9DF7A71C8A925E99F5085313D60FAD25C1BBAAD28D4AC2B69062D68F39 +0530A976319A3904CEE44DC9451E441AAB4780425440F8C499B81460B5D3E268974145117ED843B1 +71BB14AA84C3A084A7D8E07B9979260675D5CE6534DC176DDB60DDE90F6A3674F67462EF78195F8D +FF74FB5882B079DEE31FE92816F16CE1A70D07752EA25FAF5000ADF79BBE7D17EB1BD2F9BF6CDBB6 +F078CAF97986442680A8FC4121866F9CE86C385DE34E30D8B9768A0136D9EEF79A4B38EE99CBB9A4 +D32316564C9D56996E2595753EA71BEF684834FD030D38BB100E2332B026B046316A53270A96DAB2 +182E994E91262FB03D1AFFBAD623F1689228409884F91DBA153030870A7BEB2C7EE2DEC51875B137 +33B7929041F8D23A94904BD54DD4BC9B432DD0C78DD81639F46D686FFAD39AAFBD1B6C1A37E248CE +48F23E12464D5379B4AED0D50B5A41577E6ECB75270E9AD3EA7D0FC09DAB271FB18B51DCFC0069F1 +5D72546E6C51049F3425AD005F88FD7F02042DABE9F097F9D6A076B30D8CD777B1EC12BD163FDABA +5972EAA61E3C87E9AC007A052B1A3FFE14D7D43C7A0ADC89B1DD4CB4F9C762A84A6C0701494B2D8C +4E4E1A9245738BE4111805C2F153A20ED9FECF2DCF4C8F7C3BAF84D60454A7403D4F5F81C6404173 +A7BA81BB0CEAECFD493D877465DC5735D43E3102CEC57B8A589182FC65A4704661A9E351FCCBC731 +5A87E62F65D24EEB9CEE979C6E10DBCF5C162ADB926EC8CC9BFFE381F6B8A3AC0A19D1631BEA2938 +731AFC99E8EAA39BC75DDB3A39D01AD8F0BC1838F4D674B9BEE9F6F7BE4D9C8BD97E8D171EFF330C +15B76614A1FFD25B3BE19E4A201BCC850F926ED51616318C965AD2F0E56F9433B1247C6D5B72EDF3 +D408A3E0674A509BF30BE813A5E669D72B978794683CA8B85E3469EACB167C30F7666DB5E081B81E +E99ECFBC1704B9646B1A29E4A4CE5654CA8409ADD60145DFC54225BDB8485E39CC98CBC3F38FD0A7 +97E5DFC2099452A2418C6636BD2D5F6B24345ACFA65F4E7DBD2D0AA0C1776A4920B4466C509BB5BC +7D6627946C4DCB38A27098B7B5BEEDC2B3BA18F927077F71E38644597719652037621BB350BB5369 +DCCC073954026E6438FD8393DDB3630C4473F06D9FB9E422E435566C396B12FDCD5605DFEA232171 +CD8EF298786806E9159B84599C26D4C7D8C3BB064665CDD072E2083190372AA808B2268B3FEC8878 +B6420CA829BCF995DC20E067EE6B8E44D2869D51BA3AEDD1763F7F8D2CFB8EC41E6E9E0129DE5343 +1457960CC51D546B10B8B6CE08A1C2B79FBA448DF9783D815608A16C55E589DCD8EF6B04C66232F4 +7A473973A35618000D79B8173258B7365C9691DDFE47B16EEB08B28F881828B946FB5D6FE10ECC6A +FC4EA1F762E90B3320403382E42AF4885B183AA48DB5E4DFC9A54E0B4FFBF7C26EB17A4F13B4BB93 +12234434FFF05549E7587BA0373ACB3E31418BFAF400D8938FC6466B94273D1735306AB912AAB13E +31DA3541C1733E2A7E4DA5B82767D37F3084AA7A7C488CDCA7ABEF77D19E42B4448ABBD346E9BC28 +8ABC4540C0A1CFD0BF46C5BC7454B25E27E9906A3E6CBF678BFECAD1B19B4E42398A210CD567EC35 +FB115D5C0DF0EEECE593982056B0E1D14C292F70B3E049984F8881C8B477956AD3140B4AA22256DA +AC0D11C4126808B5B9F922BCC5F24A77FF352E2C621A3941AC07A20E550A69C49B1B87D116EE6F2F +970918F0F1A501166AC4423FC212E4EC8039AC7F9C212D864F418CBB92948FBD588228108FAC1AD1 +837070512305C110F0FC3FAFE6E1529C2BD0DDE868A9EBE5137DFDFC5C12A3D08014BF0EE27B1080 +02AAD6B607F5C5C0F1B1EED3C552919C9A2E97204A8127F97B1066607ECFB47BA95EF2B51F007C29 +3B2F6A63041A9C1120D9CFCD5357222E5B02DFC73CF94CF9B5CB00EAF073E9BF253E30E09B50341E +57BF245A746EA31BFFD0B00201C34CF0881BBD1006BC9BA7D420A48E53686B598BEDB3449924EBA5 +8D5DB1B1B01AE2BA281D5758C99EFE38ADCE18F7B182FBD0D0622A6EA497A4E7C00C7D17299A2765 +EFD8DE376C214D01A21819451FC04A0277EC84A151FF93903D61C78AB7886911E36E12526ED855AB +43F6289C1890222602B8EFBF15782B374AC1E580B6E963403D6D15A051DB8558F2E61C0B9476C6DE +5D4861585CF515CE951732F20D32969F39192FBF1690D242AC04D47E0C53D467D0FE4656B9526C0F +7F852348B0437737CB0F29ECF9B54A5E17185236DD0C16349C3496F3ABA569EA20E343F6D771210C +39DC932DC65ECEF94575C6E76902CDF6C8C8361F9C757A2577DA535187FD526699917CFE0AD438C2 +A758727B306BC7979547E68B94E87ED820614BDBC649D469EF6B4E4E3DD2EAEB5F80B22FE576CED2 +56495467C76A75F589460061E03F3A1B065121A5ABE3E2C51148B3DDC9F624C97889AAF7FB84B158 +C015EDA5670746C6359D27B0C2BD65144F2B88A64331816DA904572BE398E015A9924218B3EEF951 +23AABFC3AC8217B7B4F691219A1C9DD0A3EDD5C04E63ACBDE71B423522532561F4B71B7028415C34 +37E346BE728A415596AB749015C1D59BD8328E39A850CB98085B34B57FB52DD1D154F98FEC49B3AE +BFCB1672762E4D2A1ECF02787F59DF1EBF2625C3631BED849B298C6D226BE4E6EA2AB66A287D2BA9 +2A6C9C612A5F849B3CB3C25F17164BE286F6E4F5E7E4C9EB17BC68AA5EF0190B64696A570442E1D9 +BDD1A30E7692524E30E4B4C3DF84481DCEC6E10E7308E65DE9D90099F3FABB3F4F766BB86CC98594 +6D2003E21287761A7386CD8461615B570BDA015F5EFA23D18E83C325EE444EC166A1A32D9818C2A6 +5A092D44156C06D3FD079B92450B8A491CBB3529DDAC7D95AFE8EAF33777FBB265FEB8A4B9AFF2CE +CEFFF49AFBDCF6C4197497D3B448866D70EF28D8E4B17E7CE95F43F64BB48C4A73EB84B26650F62D +3E5199D64DB0B5B87702650ED0B850FD5D16C848D096E4C7E61BC63B2A3ECFC099CD713E12C91A65 +77A88D6F55D348617C7A49890A86EA8FE2045704B5ED529DB128C9B19EE129E5FE6498CC97087F6B +DE96007C9D01CE9CAF75646E5A5B32BFEAD9362A52223D746943A2D09C536CFAF78E601BC2D2F0B7 +63AD722E3A7AE7069D65F9F2BDED7278511D0120F5EA071D41A69F8C2A2D720D3B24B4BE61C83FFB +EFFAE21B0560A6FD1A44E53E42E0D10E0E93F421A8A7E167BB65F0D7F1DDE2809FA3CDFD931CCC69 +B119C83238C1C00EC100D8E7AB1C7FB02EDE97073C8A5860371A8132BE391EB1C397B61F93876FEB +438C288EF2E38DDCD182A5CFBBA994A94A1BF818312CD8234215FCCD7C240A15AC01A885E1179E5D +7D6305DC2F534BAA141F25EA6A5F356486E5FA0AE3C6980A9F5E8E99E7AE5B95AC42977510970245 +4FC951E4319AE4B1DDC9B07D0998372C0A95ABA6985A4DBE6DC633154FAA30ACE689D36A7F17011B +F29CEDC58A6692A8B3B0A5742E6CEC2F69B255BCEDA762DEE72F125EBA98891CFF4D88AAC14188A1 +8D81424979C9079E44890D94EE094D4CADDC1C7AC5F6791FAB8849CC0240A579ABD800EFE3AA4EE2 +F78119A3C2806C05C2B1F17940BE73984982D1C0065433A9BD658EA31AC819DA9A11B87475BB565C +C294B6F302FE3F7752ED9B963C5279B5F1196762D0E12E6DA46FF9A0CADE3876D7DF695D8965CB4B +47B351FA3F759811269376B2C3134403633FDE27C9B024F6BA81F3E1699CF64A426618428BA6C326 +6BF016C5DAA5FA4CC82FB6DC23FF2D742160518CD3A65ADB38E53F1067076CA1625466E0C64670A1 +564A54CE14DC5C57D24A12283FBCBFFD0FD594AC2A56EE58B552F7586825E4FB1EC23F8221711692 +C8C56F42272B87EBFF3865191F1C11943BB76D8C0CFC53ED452AE49404D2C8193ECC2A7BB8CFBF24 +870ABA38D2CCF7869E9363DC0AD94FACAED5922B324DC3B6FE83E7B34FE29ABC1EAD62B49FFBCB81 +1ADBB5148D5AC2743E3A058386036FADAB6FF071BC1C3B8023F908B6FF48DB0AB1C9C67487C35211 +D40995E1892C8B66AD6C9C6203F6F8B513B11117B10DA8725AB45B4437B5A88A96AF3178D856D601 +196E8162868A83DA64E408FDDEBD14D6591881EA652032CF2F88B3FD6C0479C8F89AC68D14D01AF0 +CEAFD95AD146E68FAE01A07F39E7A0C5E4FFA6D6A91D710827CA5ACFE7D1F946A8D7B67621D60F53 +41F32C12A6EFB03AE5AC5373A382C044A276F6B41C173D0AAAAE0C1DE4C3CC71EC2637225CCBFBD4 +5EAB92BF39357C57195B410F74283585B12B926438AC72AFADAAD2D0FA2CCA728C8E86BD3FE75D47 +B8BEB96AB13B5480F7A3D5741EB51E3E40C21FF2ED7D9221D9877C7D1A8CECF394E4023FCF8C4EFD +B38B839499FF5CD96A46AB4FDB46F35D3B48B91757C0159328120E93CF1F2739E936E28908FB1947 +1D3AD7F6F1AD2BD1EC364986A411CC1B547D0CA104FBC10B1CA7B638A60E75485574034561DB345D +DA68415146AAC632DFA34769B6ED7D7D4694E92CBFF4EFB16B55495908102E85E827FC623CF1BBE6 +A13CBF64E878E1A2A159948B5529B75E071744A5F0E50DF18C110B0AF117CE7F33F8C959D4C98CED +5A9D492AE6F56DA57B0F17495DACB130660BCEFB064FD8309D965ABE8D2BE98F6898C1B7A39CBBE3 +E75DA0FFEF6CC3945CE76DA3BE915546FE8A5310130AE0ACAA9AB73C7E041C00533B4BC7724657AA +649B9388B791AAC5EABFCDDDEA2CC67A0FD0AE9BE37DF9AD40636538EE55A83F60E9E026C64FBD8B +220CEB46E67410144A520FCEACA252E8165448F84D8EA083C793AD09B90B3EE83B73FEFC3365C729 +E3C738894B8C01C2F8AEE0CC8B114E1175EFB44CC4C6CEF5C8754B1CC7CEC200AD8BF1189D741CB7 +5BCA4E88BE959E32216AD33F674F49AB20A354CF3969F1611A95D3934E148831AE7C81A7EBE3C524 +4F743E66A82E10D16CC09F8194EA7A596BC5981D833318AB4F7DBF2ABCE543E410B649D18D146F01 +486159683DF61A3F880F9B21EBFAB77E908C6CFC79F89BA5F51114F0BF7C3CCEC7BF0F3B057C3195 +CFBA6908E31E0DF10DF69163C9DA7BABC00E9A580FA7FAC202910615BD479BBF76FB8068630D1EC2 +1CD2926D351E869E16C2CF1E023CF04D4FC61607DAEFEEEDFF5593E6023492F00029E2AE4B4A2C14 +50954EFA2792F32B4934A768F892171245A1E2F034E2B9F39833F1B331A19A386BAACFEC8C929BA6 +B67CD8922BBC9DC005EC3976575D5B0508D0717C6BF11123EA36D8FD37FA77A6F1F5AA84D4AD8D25 +B2C11D1877A6E2F9B74F3B5829FAEFD4F7209CE9785AA6FDE68672554A6F29D8BF03FE108ED90A7F +58690FAC399A8AD3A26899072B832874DDB629581A51B3325CD9EDFD49E890EA8959DB937DAB83C7 +77F2A426B967AF5888C33A3635B78D647AD6BA441E222C958EA58D61945F781D7EF409771B89B202 +42AD7D07C2EF592CBF413C5FC89EC30FC9EBEE4BC63709AE33B65EE3091CECBE610B847E12C556A2 +79C8B114C3E460822D3330ADFD72BD69F54C08A81848C2002A08326CF3B09B1305490D35AEE59179 +08E1604ECE75BBE811A715AE8AF7EA9C371B322D0428EDF4C893FDEA607E70E1B6F6614947326101 +EAEF18E29BE0557D2A92CF1FC1505E8B434BC368CE07CCAABC0774F8A63E1073FBBCEB3F4052462A +A9008A1E53F188C9EAE339FABA74AFD6D60F47282CD9FF721F64BD51787F3C13B5A6C5A5F7861171 +0111F5E0471E206D72520F1DFA465F4A23C71DCF99A04CEEF11B0E3BDFC35B7461A60753D3AC26DC +50A5956C9195A4F5226388E0953DDD03AF128A98F03BDFA0602CBBAA20AB9ECCDF7255962A332E16 +D4380762E498FDA4885C64FF5F9B480DA487C58E78943DF62616E6E2C69EEC8836DFCFA9EBF58938 +A878F3E792E8BD8C5D6DF557A5D82018DBAE1CA9C64BA5AF8E21BE1B6680FC5DB22422220B776E9B +A0BF1ED2B7212F8BF111EC8C8C77B223C05EB5E5F1CFABD2D037F4BA0F9503E2CD83F4519D180476 +63F09E308883F5DA5228F83045FF41214D2273B2FE0A9017D5E0557BC2A198C35D1E7E81F7965444 +5760CBA1D3F05EA4B90658E53FDF0823BDB1501ED51DA75C47395073D8980D1E3504E3F67DB3259E +4EE73A87CFD96F84E221796573958D364A51E635FC55478C9CBF9AEA16B7D8C25F2115CFE4B7F598 +54E24968833BA0D64D1D332A666DFA2A3FD71B05A26BAB7DA382907B13DE0B80871DF184D3622B62 +3D7E09BC32A4F6EA2E6DA450A906EAD36D53FDEC7F83E101FEF32F4FAEC581B000686D86A0D3861C +1E67F18A4C4647F51F978484D9E3100B37BE9D20AE84C085461C1FBF929C669E936659050C2627AC +1B019837BAA75757F5B0A82E8AE9CF2111931A38BFC94744E2FDE3F8710342AC615286E4ACE7F269 +743AA05463AF537D9416230ECCA859D8C99B7C6E70BE7FE11DB698589BE9E11900C8E9582A4EF5EA +94B5F62820C90DBC022A620EC536E06CB8BE7526A789996D0E741AAD980880A33800A6FE92286CCD +02C9CB407EB31FB95D9C9F4AFF38B37087AC582C1F7B64A7C3D2202BDD62E9AEB31BCA85C4CF323F +03DA9D318B91F78FDC0D266630F7444ED068B55C05461C97552366A82C2E743CEC353D51028FDCF5 +403B3B74D379B82EB69C4380ED40239E15A86B2E5C860891E26781CC111FB5705E3B7C7AF1946006 +54B5FA1B5FC54FD0BA43666E7BABD2C91C859F393ED49F7123EDFB648A3D6152F2C17F7E438C0A63 +8968AC06B4FB3F77F64F358AE063820BD33F0213C85C40E4D97ED100EC2DA1C2E1EA258BF107AF67 +5A9D995F60BFA37222B9C2B325C0052BB8537D2B27DD43A129C7E8FF42757B3AC9B447703D382108 +DA520B8B3BB3E8C7295B776B44ED28F863B8E1F81B0BD1DAEE8A171525D09D2620C04DD3219D880C +2ECC79282DD7B1772A9CBBCA706909AE8BC7798E6EC7375189B6CFCE8A875849176E5913B85A18FB +197A33CA4B5B4058603CF1FA79A56856B43D538E9ECE117D99AFA73B57E307364F553644DE01EDB4 +6234EFAC13046B6E047ECC8F63942F20097AD7ACF0A45C0501A95263DE9439A880D6B5C5214D2918 +0A54D7FE9B2E627EF49E189B59FCC78745E878E45B46C0A648955D3EA8C935113D94F92EC963F66C +F3CF3A526BA71CDF3CD4CA69EFAB08B7389E3390716892A4872BD29DC1E0889A42D7FFB4190E9A8D +05D84EB9C5741BE6B02716BC75E0106F5F94BD3778BE985E03860D27E44088C3CB2A059DEBC420DC +E3A8F4087A9548485E616C409AC400DD1C411CE4B6A229D091B253EB68F06E43511EC5AA6ECA4D6E +4818D6AA2068DA1AEFCA377611BFA816B5215182432D5683294D67A7C1FD76C52233087CA44943EC +7280005E93145F5E7AE50100C18364E1B36741E9647C4DC1F68A58EC44095920FDCF05532F603717 +80F78420077EF5C24D63E26040CDDFF8DFD65D871DB943F50CDE84900C1372EF33FD8AB9889C82F9 +4F61A0E6842219A0F39EC7B232CBF802C4A744F33159432E827006C7CA77E480A48A9B0E6A876158 +8A3102E3F98A77BBD62A3A23150FD140D3941773BF7CBBA2338FF37B9EB640558A2313E8824E8E62 +0331568A9B76F4897198A709F9313F4AC40827D8C3A71F2ABFF02BFD57D30D0B14012FB5C39B85AF +540DDA0ADC27A85B31694E8D7B61F9D9B476571022D98F2D768246550A877293F3FF6ED918A498D6 +A600223E1A61890C49ACFB60265867CE9464F9C32C59E94F7641C3873FB4FA6EB237F8ED94579957 +270D6FD640BD9543E683F2372CCD7B60AAD269E03A72C5CDB732B128818D41A6DDD2BC139F7D3911 +F48E1B1D263DD4AE8E4CE1A686F3A00A2CBF48978631CD243566E22E68F8D7397134A3530EA3745E +4F1EACB4D6A5FD84C3011094F37573F7F9902305020C53926716D4780C6B0A257BF711AD94C83F1D +41A02C1C7DD203A3E6E4B14EDA2FDBB36B063A3E074495F626B0EEA146D22AC33457F44F41675967 +6D2A0566EC2B726D2F0540ABF225339F02F406D4E7A62E5233DDF20AE7C86CA0CDD561F33C422654 +BF2DC3685CA91BB9D4B09AC8B15A24A99FF56E2894F11F7BB4728FE8F0F5B799F74F475D2D01F61B +7E9E0E541F7FEB8A557486D7DF2CE50927515D833BCAA1CD9BF7A650BEE9E003A5951C98ED147C4C +52F64F692AB281984EE65A47E44A4A5FA93D6F18D276D3B01C5E5F6135AC6940524CD713DF4077FB +4943E8AC927A68489EA52ACF7A854393CD027EB52EA2DC6234EF034F3DC742D6DB5A67FC21D22B97 +146B9C268BA97C30161CE01EDC69A6A1F05EFB0E06F22644E1A368F0E2C0C6C1C832878E0614B74B +D645F5CB293CFDB7618B837FFF14A1210AA061C8C81867244305B80DAA73CB25A417228E9559E7BD +52C119B0CCDB7C4DCE7E1B9F7E8EBBCB575E5BD213BDD6DB88769DACB05E5870232F0EF82F448559 +187423409EEF756BA6247493BE24CB1879B5DD822E03D0ADEA1EDBDD83D3FC46759C679B921F0616 +F27212903F728AB44C1784E8A7DCED0DF5625A7D3F48A20FCA34008184CECD145CCD98E31B79E174 +CF107E8F35C40C19D86B40BAEE6164353408801EDF75A619FFC5B6FAF3F3A95F64795CC40C1F8963 +4FD8C13852D265FBCEF834C800AB46E3E8167476B23CDD8AFF6E2F997C99A86A9CB30EF8C853154D +0D89EEE9B9CDC1B4F27BDA32432A4173B55CA8D9FB50ACB2D886AD8E5862FFD5DFF224BA13C8B8A5 +4A7F1A9F987FBBDBC5A3C3D762A5BE309D5D926AE5093C40AA47B3B1BD828797CBB9BC9FEC9D19EE +A73D2A39764816113A8EDC6CFA6E605AD578FC8E30ABD600658A49ABCD5AC54655D29C50FDB72070 +169D1B389F114B7C71EF95A80D82AB537AC8C165D47371FC142A51625029A990A577EB1618480D72 +6DA93C98E5C5F24F622A850CDD94BADAEA91D4BC32CD50CE69E9F00E77DEA8EC1D37916398FB7092 +402605359DF08AFE7B99C76C2A7C70383F28A7C000C696F45291BB8F074791798197CAFF1544C76C +EEA8C9E6D76EDCBD92A86DF889481F3BBFF0865442264F0EA40D3CAA69AE467A08003F9C30FF7F2B +77E767580575398462D5B1171DD441D8986F33BC7BDA17D413EBB6B7A32642E33F20B284BF3EDED0 +02352FC66C6F7741A542155F4A159CD778BE56B9492CD95115C1A06189A216CFD2E6725965A13DE9 +73765A05114D9A5A4BE0615AF8BF6A5EAFF84468B849954D15BEAE1CDD57C435788B331905C01421 +B50F20B184506A0BEF746330BC98E9C89AAA8F9D102F158043BEB6A682059A1C8B8CF67B2F3D7AF4 +D8BBE086254CDE53765E3226BA2F95AE8063649F9F94BD9519411DAF8A0287307335668190638806 +E29484A4FFBC1E46B1800E03B162C23B1DC0B4C0DD3C7ABED2F00762972EF06EEB9BCDC7B3F39C70 +BE32789D366F073AC3280C273DFF2979507671B3E1E7685A9A4F0FD3867F96DD675BF05F25ED986A +79249B75F182FD73CDA2A6A66D693E4CC5AFE3402431B2C816DA1486C34BC9DCA4E2D51C868688A7 +787CD10ABB9ACA14B7181369DE89913CD8FAB58FC84519EA2AA14E54B7A8CE474F213E07CF2DE2E8 +88093DEEC937526816B71C96ED75FA9E2EDC0F9E6E84569C12BB8E39AAEDBF546630745553D6084F +F9524FEC6A7264F88CEB7EC3358E923B392474E3A48865564431662988FEA768CE555AB0DA48BD52 +6A84B0CB17B4584066C1640C1023D91F7869EF0C4D701BE121A6E3C832010427490758AED7A2B30D +6028F2215AA44E86D852FDC67DA5CCBA79EEA863BAC9EDC2535B66AB0E54EC4D4411390FDEB8D1FB +C1743F15C3B68DC92A8659E7A892D5E53872EA51EE8CA7EF51103E87C29A2714E907C79DB9CF3744 +1785D2F73A1EE58550111A4D9BCCBEBF2E39CD3B93DCA300FAC3ED1ADD8215301E5766C30C8CF296 +75746C5A77BF1FE3CD75D25CF193DE8D9AF02AF8F7A6E8F84B548058CDD3C6998ED13463FADE7391 +26D83D3CE2C7201F955382832E32C10DCBCCA35835985B9A93F8E3B0208BE6E92428787C47D3808A +0F77B8F1D76E6BF6A17FF81CDB065180E03809D03638307BD7BF5CEDBF64904E918FC805AC905379 +928B816480F6E3BDEE47042CBA98539DA0E113B1A5F23EAF1A3210BD18561985E6436EAB90395DA4 +77C7A6D7888D2377B3FC4169368357D880CE041E1F7C875E956600DB7D9B35D1EE66BE476E9DD806 +4CC02230276829C2C0A098F051502E828A0CC505AFD8C3DF293DA1508AC4D25866BEEE6BBD5A230E +9C2DCDD4F06883936381F476DDCD86CCFE15C2CE3C3243E148CBE603B8513A7CE7A6910A66A90B70 +89E5CCD4368BEFFF2BCF8E918BFE0A1B069AB2A914CA7BB91A0AC3B3C0B060FA1A0316F6135E890E +E549315897C8464496CC6DEA0F7E3AF43FFA4C3281156067582CA255B1D2E80F999A3AC0402BBD17 +01824C3BB524130F5B82A45275807BC2F3A0655EA208F968B297F98C369192C8ACA26BEBA7DC4506 +FBD1305E2EFA4DBE5375281A88EE2D6FC88FC0A755E72934B4B58F6DD3BDAF7171A4A3C776576735 +2492BFA9A7758504750AB7F38754683B70E9E293CB1CD7B23BA62BD7397ABB84D7EDB22EF6C3F58B +3EEAF656E361747ED04020163253D1CF3F905B5E85F83FFF30AB2778CAE43781667C0F65C8FD404D +6B9202A99EA76AF9AE1236631550B66B063847180B6DCA832EA8DC4A6EFDB674B5A26552A7C7D54C +2799C7D4E03C24F661A91103086DE3A90A774A6988347656344CFBA06065AB22476BB09FB68F9928 +C0045F2764AF643CFEF0516D87FDE6DBF93BAE2829B176CB507BB99835E01BAD5E55C2F8798C93FA +35EB3FEF02CFA31D3D21B030547F86D27B9448D68E2B155A65C742BD2999DAA0C3AED64447B9CC67 +F7AF33B63AFAF25F3CF7EF86657FE8F952288CA4B691D369E8F1935CDA44A180A6767560C2ED3F2F +CC38B6BD7991D4170C7C566D690A8A25BE03212A80871108D18CCEFF246623E653107631F29227D6 +4754B2208D19F84E547799E691CA473780DDD56AE620CD953D5133D135E3D51F237078FEEBB73714 +54EE633CFE238AEA63F9999E32850E6C197687A0EC4E5908D2A18C5349627E336AB5E3185B218228 +603A4B1852069F5EE849D571B8387DCE1F8F8E9FE94FADEF128BA83BDD245F8C1C27C11F2ED1A8AB +2D6D601726842CEE744EE7AAC6B6FA16CCAA39DBF5B3B1D47339F31DFA562671A9CF7DDE6915FEF9 +F19B3E068A464DD350A3AD146D1A241673B5112A4A8768F976723E6E184790C0604506C46591BEF2 +106C40789B733331A80740D59ABED39868F80BECC2AA21C400A0BD0CC326D186FFF9EB37680F1EDC +32AC78F9059280D07B5FF2E354FED545129FA5FA8F3D4317FF21E027602FDB2522F049BB545FF4DA +60248130F81F4E348373142F3148DED038AFBA818F26D5B49FC02DE9800D894E9239C88EE0EDE431 +F8083697CB0BE3B497473473E5714717C914A1A926730C249413FEA2615EF72BDB0906933387A892 +370F77EEBF62D26CD583EE643B02E323821379C0DC966407D36AE3CDF646B95DEDC7D7FD0F28E950 +78F12DFC0D6400B327B743C548A0A3517A175A7ED963ED756B1E107AE7087E2446BA702CD4E26E2D +CDC1A8B697108B5B5E81E9F03105F220C72D4AEBC57665887C8C7964089FBE9424120EFDB14D76EE +F8C6F7A30B13E1AE90CB9D93D2E14BDE47F4A1D05ED5B18D32AA39911B92D24C93976ACEB7EF597A +75161923A73B2CC761785493D0EEDC08B5AFE95F3C006B41438A0785C962B070DE2BD096CB63B847 +C87539880AA3D3FC5C345E0992D7BE77C6CFF4948617FDDA784CC55652192B0ED775129C4EA4245A +41BCF3875BE319DA0EE2DAFEFAE920CD2B6C6C2001762F88C0C5C05053025C0349DB17104360FCE1 +5D7F3A8E30ED13155A74FAF91DC77B8AABDD6FBD5A1EAF255DB209D7F2B90822296B5603FB5E2CC9 +5CBC5F7A6044058B8044ADCE73ACFD896177F1F70EAD2F6534DC3AD755AB2BA87126D63CA2E9C441 +DF0965BDDD6BE494E58D6B5057A561D1E31BD38E92CB73C1465AF6B9C001F7229059BCA4104847D1 +639E124E082F7364B56548BF8112D0EB461B316B2449049F6A476D36D6B7C0C1126C08F2E9A1246A +3B5B21E7C8FAC6E23B82E33A7783E4F31F0240E96E69C9444E7D7A928636CFD086475DF1E0A28464 +81387BB2010655B9F81A0744121699B4905AAEDCC84BC5D5AB3674601DBBB651EDE7B5DF05C8A463 +DAB41F79706D285C4F9063997F7AC8CEF35CAD51FBE5F5BB1B3FA6DA2C3ABF2B3E925581349728D6 +DA0D59C1EF6444539742EE9A23A5727F20CF9377F4F84DEA420607015A30FB14632D084A2DD181BB +02FC3A84FC499B318156B675B9CA3CCABD87FDB2497C6705FA70EBA43ADDB6CF961B30E8F6AB9F84 +E1DD8D6DB3314B34B7F7AA3BBE19D5BDC75ECADFD8EAE19E07B387A1FC586F0F30DB695926764B54 +0D89F1D854B0FF86528AD9523CAF56371E29498C11AFB2F4D5202670C834E930103F039D13348824 +16A49BF93B84FD3CF1209EEF7D4994C8302436C0794497461C11F5B8BA152BACBCC08AF8A15F4A4D +F3EFFB7227CA97FC21D2D0356C93390C749CBE9750B821F1A7BCFAE2C8BC6D9A27F844D8AD088320 +79ABF0EAD8ECD4EA72846DFEED021857F33C1ACE4C07BEC90398B629814C498D33BEB375B9A53DA0 +F926FE6E89E70322C72CB2DDBFB16B13EF7A4F50DF783316584C6AC2BD7D9029124933133B2229BF +74A228868AB30EA5C3E87C78C3F0962199480DBCADBEF53BDDE45849DA857A4FD85B96682F1EDEB8 +5384929DEE4AFAF84C51A09F5D572705673D885070303FDB47DC898F874E103A9E7C1E894115DFDD +AD81549C7375D4AEDCCE2E52C13E5130B47F206F7C5AFAF1F9EE83DA8188D70B473269CA280A6A02 +DE85300B93D8A4F6B402FB5DF58F1327470CE11CC63ECEF2EFAA396A6680A6746A20382D9529B58E +7CE684B39AC00F7086BCB47C2230DF0343BED9B9152A61C9826AEF9E00A1452D91305CF05490D4BC +0BADC9C6FCBFA93FAD52C3A80705A1956890497557C0873EBDCF61CCDD2219354A4F5621AB33B119 +32065C1D990A9B68858331EE7875CAC855F98563B14EF9E1060BEA90F195AFFF94728AE935453438 +DAB35123D0E2699475884DDAFC7307A5CC06920F35341728D85965F5BA86F261CFFCB1E29B429F97 +6970D42D10E6AF6C4B792B4384122AEF2448E22A58D3AA007743C71324EA08D06819FED14AC1F22A +4F0BE4787BC8738E1CEF240677571C65804ED3E748D72E89C94B6F310BE748FAEA31EE246859CAF7 +A1EA17CCB5B246C87EAB771E2AC5D378650191081514DDC2C66878E3766CB20DC49F630F2743A7FA +ECBE9DBE9E815A3CB57DADF2BFF5EF2FCE23A56298A30A2E052FEAEFBD698101F9DB992613706693 +CB0EFAF6F60C8BB5E7D0A50B3392B9831EF3A304A846CD4AF431E9F018FCD3A5B16387552D55DAEA +683D36257418AAA0E7BF8A03ED7BAB114D7C15119E6C71C1946BD7903C1C42E115E954619051B853 +BF05AE316E15E619A7DEE498F771E809D9435969C1056402725EF40C0200E083F3EC6E0EC27B8ED3 +8DFE32EA0E5E156AC36C4BB9AC5ED111A11678339703F1B9299345AEB1F251FCEFA11FB3101CC499 +907DC862B4463D5523B9B25C5B69F70AB6B29CFC1DF1ECAB8227EB3ED1F882E90B12080EE003714D +403EC43B7B54491446B6A3DD6EB641EFBFEF060C45E873E7398025B1CB7065441F1753028F6F8C49 +A96801C0D598E098EADC96A21117F817B6FD6E6947642F93E22425A00E8F6B592AD50B317B69C0F9 +4047386A45E5EBC9504FE55451A01EB29DDF9A41D4BAD85FC84CE280971E834F06CEF49C8C20ED2C +EAC889F158CB14A8C070900478804CFF1D1637CC880C81AA287D8382837FFA8F41FF3C9DF2F22CB2 +0044C171E4815D0D0F6C22D19A52114E780CECD71DAF63427782E85E463DCB333789F496340E8CFF +885A9D9A4250118B439C71C6BE51A9338BE29251AA794EDC67DEEC6337FA63CA9B03C1C9F75E733A +4A918646E7BC9792486CB5A4BCC5F84FBABDFE338C3792254A3EEA3D88903C2C47B91E076259DCCC +8BD3DCA90ECCC832C09C45141C6242026BFE309029A562C3EE0FCCDCD40E5CF265ED9C3DE582884E +0E14819DB98B3AF734B1B3276AC41D43384EBE73003D15CE39FFCC04109583390E470F431B4407F9 +8550E138F96C4564B494E5480F47C853BDD237E27301F55E42A3BED18FADA152572B7B465A581DBF +E7DB2619365CF16D71BF8F091862B9FCF04BF8D0859A76F46E7B5712F2757EDCE332D3213B8A30AC +2CE7D7797EEF6F30904906B0805DFA7CA36D32A20D989858497A66CE72491393DD79332003D55C09 +5A5AB5DF761C4BE5C041FA8407263D604E53091F7B6B15496245DBBEE96A63F10FC2978D99E65731 +28689366FE8B0BADA48B50185B861BAD03E3600F22BAD4274F2542B635F6C7944BEFC3BC741BDEF1 +1A8DD659038CB40FEF2E16AD1AE7EBEDB7D9BA15FDCF26355331505A386DD7399FB999535D6061EA +BC61DD76EF3EB457446F29D0BB6EC2FC0AABAC20B27A3C123C27BC27A76336D0A0A6D456DA070367 +4D959A4AFE428E2206A511BFC80039ECD56E75F69786DA0A8084D81A66644DD98B6018681F1D70AD +E09BD9BF3D16D68DD5D0A03AE26DCF1552549E459FE190B310A8776B2C8468C14CA8B1B9A7AF2956 +507A3B705AD75A17A0EEA7FE089273353CECD07BB8563465EC8DECA0EB42F43FE3664EB5F31E1D13 +24185539B28D508BCD065ED576D8814ED3FD637D576F027927162344AFB0255A91FFC616948E4E35 +8867E9FC76A9AFFACAEBFFE110808C1532A2BBB0DBEF3F010E45FFC73F228D28F12E98478B27397D +8F456781ED9E19711DF2E9EECBC3FE61F7493FDF1A59124668A91BE51F122F93DCA4BBD22DEEA339 +E6EDA3D6EBEE03DF958113E1CA49C8398D2C59DA6764882EE3663F62A55AE50A7E91B4FEAD1B11FE +0D50ACCC5D75F1A515F0C53616A500F1491381DFD0E2477E402AB0CF9F67D501A442629C8593ED5D +25A72EDB9746B02F2B0F0759CC9CDCB4C9D8B4519C8C617E569B432F0CF6890372AA879CA7DE46E1 +10D95E230A4F0E52CF65811C54365DF4A3E40D819E2FD379B47DA3233D0DEF0EFBCE04AD8BAA3888 +4F6A69FE5C373E38AE0FD0241480F2BE7CCD18AF85916D2703A049779FE7398FC47D348454CF03F2 +2EB3FECC064606957898B5643464845445C25C0C7D685C8DB042AF5D5882174374ACE90081C68678 +9BCA96AC602EB41D317BD652293EE628951875641661EC86A2C40A42E8F0813A861D41A0F5178E55 +43651CA0E99150462DB5EE0010F00DE6D55B0D7FD7EC5BAEA24ED3E90A7D6A0589761922B91A6A91 +3A7FEDDD3B68254D89ECF767CE8E27F966426A8B4FB1B4085384FD09D63E288405B78A646F44C87E +EE22C8596B13188085479F75F63D3D97A28F9C8306FD207DBFD38DEDF0FFEB7DD80B2A3292DFBF1E +D605ADF1B33E85B010309E3EC058FCD922B1325FEE71EFF2DBBC2E68DB52D513E024C01D47CF657B +B61C9734649A4AB63C0AF4720EC3EFCD82DD3CA6E80BB63BCF1B8DE810A0C6C517C63B76FE68C0B2 +86867BE102424FC31C4937048B6F323D039618586FC21731005D949E7D802A430DF8D2F0CE99F2A2 +376C2953EFC4184355E4D12F422C9E1E25C4DF38DEA334DBC89B540E14C61A7769D77115CE8968FB +76B27D0863CEA2496783114C24D4CC816DA884D953DA3F9B9D3AF8938BC607BF26A071956CA07E6A +5509EA2F5D80E5CBEB98041B197FAC760976EE75B470DC20AA023BA3F63C2876EB281FF5173BB490 +D6815604517AA1B1FA0631401B3C1A04CA103E2CA4ECCD83874D9CFC8ABC134CC0F9141D9AFA5684 +8BF222342016C556C14B3482482DCE5D0B6EF1AB522AA1812BDD8DD3397E05327EC12748FC480842 +9B97202E24E1DE0C7C0D272C046BA73B37D30930C5DE5A47D96955CB0F5DED8F3AD929A8B42D2839 +0458F5910A0F93610F79EDDB27078943DFE17C716D65F96589769349F3B66AB7B8C004CCC59EF688 +1F745EC7129865A76F9C2D029D4660CCFB4D5F9D412BA3372A27CB175E9D65F759575CF14A5899A8 +D31FF039AC02DBD8391C3397428AC0D5717C005200790785354813C8859BE90E0E17914F6CB9C674 +F1E9A9648657B54E5E1F52756C4F982DF74E73F6E4D40718C71D1D0E2420FB7462FEC9E457C0414A +96E475C6BE2C10437096FCA0C942E995A9ADA789AB637B648781D32DFB68E62E91C2CE7E13680F8D +31ECF8C824885FA7618981CD05FB335AA111B409C59EE337DF4E5F9DCC920A5FC0D620DC07F20DAD +63F4FF5E0EE5A2F390AF1C32122BA7780F210229E5A5E3ED97BC1C3CDDDD456E739CA782EDBF4B81 +0552368E9C734B0C78B0B8E3F8B2DD782862B74318871BB1EF087828CC173D7B049811FCF598B8EF +DE4D9BC5447F4848C98029C854F3AE461B9D46DDAD8CE67A521F3C811A81A396CB0F80F3C8D8EC88 +30532FB7F9624F7CAE0F8C6DF875073333DEB28AAA90AAF486AB8C932553CE697B885E71EC8E40C7 +835CD5D59A2C695DB9E51216FF9B77A15B0DA63717FF25B05B939E45CF7FBE490E51E9344213B32E +115C2DE14D76DFD5845088DE645B0E75042A61D82FB1753C445AD0A956A1263E5A096B681D3BC51A +9FF32EBAFFF7ECA8B59D40F0937EEFF38312AE57462C7BF3B1FE24D2BA8DFE84515270E09063CE3C +80DF4935E409F62EB4F54AF16A186D4329972B9BDF15FB08461B688ED49928429226CAD9F67C9D63 +6D1375CBB7B08A5631956B7FE29CC9EFA8D75C9E4919C8C2C54F401D2E0D7BFBA40C50CAE214D210 +C6F3EA5802339F63FC4C1C1995787617F3EC2C806CE44CF8E29F76606CD5836F6E5A2E423CD791BE +CD3F112F25657DFED9366FC4ADF90B685CCE4A5698E5FE16D7542B913FBC01B288DD13F43DB2B1ED +8CCB80159DBDC90A8132125DF8DF547C4851CA609D1F6F4D647741260E845B457937787827A89E37 +CDA06BB191669AC84B8608EAE132D10177F3FC384980F3A6E439B048A38D0D6B9CEF09F3F2D732AA +71BD058169D6D0F8C9D146D9DA046774027559A8B3843F6116B418427E78476AD8F0F81E8A6B1209 +8060FF7DD686503F972D6C42FD6CC29C083AC3D72E3751F21D2E44A572EEC80E81EE44C90FAA7AFA +BCD3ECEB98FD4068F6C3A4DED0E6CEC523C9A0054D1FC2A8D61A4A26F9BC250B8F302416924AB22E +722297888B85B9C12F8DFD2A744CBD143F9B2514C1CBE988D9CB4E77D90B2EFD5C2A528355A35F7C +4AF039C7D1D756305967B847D4ACBB81263D4992C001E2A262B9FEE2D1F5022BE5B15E1D8F1D67BC +52227344EE912C018CB73E5F47CED54FD202627777BB77AACF3EE6B22706FB2FA9062BEE87E22CD2 +802E7706322648DAA0C624EA885430175F746E1F536F9A8E1C610C4A761D07248426DB63C9319A88 +A3FA449C3FB8AC94C6003C745E6BAD717A3B2EA3862D1E08512A98E57772A62F85F1E2FFBA40E2EE +43AEC11203DA9CE5AFBF673436F2DB6AF85BBE89D802F7A9E5FA25A408DB69E51F0577DD26F94CF2 +BA2FC53EDDD6FBEB534AF15F74F66EF8D14E7FF77D8A5D284C8202DD5A6053CEAA606BF925992382 +5EF4EFFAA8D878652A4CAF2EE43ED26BF3590402686C876F86C1AE95046E527617CDD3C429BD4CC3 +F9654D2C76DD4102471FF746FA9FA379B16DF96BFE3836D43FCC0B8E95120C27370049ACA4AC313E +1D50D72D1814F2566B8B29FA9C9C20D0488743722A766436776783B939171FFFA00E04805A8B5821 +4D4F114F7B9C3C17CE7486AEA2BCC895ECDE809502BDE57981318A93F23016F056A421B733C4590E +34AB08BB348DA4A48F19B6BEFAA1DDD2A49A6C440443028333CDD48C85CD698ADAF3FD8676739E44 +400A98B575BE02350576F96CFA54D4184BA47555B8D12374B86D038D085F7FA51FF4BE2FF5981408 +999B48B2FAF305212ED54B2E371F5A0074CF68D1B0E5CD279BBC8BBAEF694A89A6C43F518D01BB4E +8402AADF34E96E9B3FCCAB4CBEA2741D3FD9ADF7AF32388F7771845AF99965A6078F4DA335EFA436 +BE36903E33A743C112C0267309F266DD44FA998C9A139704E400B89DAB952EECFE2AC09C82D9F497 +5371CCC27DA37890EC84123193314D8A7A707C217FFC951A547EE5B6D1B7C8ED85BEBD9D3F4B9B09 +6A78E5F7DF88C931E3F396973974454E59340CA51DBFEA1A00DE084B64630E26C6D6A3593B828814 +E27DB0186BF2A87EEF268AA1B135AC09B52CFE53051CBCC88CEC5657BD47F603C8E1A6249161684F +D9084AC279F57A4F9BBD0A546A87E147B62AC860911969A29B8AA20E3AAAD0079D64E6BF1B0F2CE8 +F0C54C9019207E1B403358253C2FA93A662F63B9380B65C5173C198D86A3D0DC1800D1F5378DA39C +E8523EB62C6AFAD8A0D7AD1629F2CECAD82B8FDE38975303768C7D3A08B91478EDB3C45A8C6B7725 +EA8596A8ED50B8355FB852FB8966479D12E1086223B1E6523A65FBA81DD106FE254F7309718768AB +009FF7714A8C363B09DDA73CD3F81BF9C0CD3B0C806CF3B7BBFAB73E46FACAD2480EEBA97AE68EC9 +4D3D79AA01ECC22067858EFFA9D7B7F997ABD2CE5AAA8781E5499E8580C405681CC63EEA53BB47E5 +5ECC5BA2A7A3C5472DF034B022F455C60FFF971B01583A29E211A87F7163187B190B0C1083D696B5 +86E9438FD8BAA45101A5EDCD1BE5AB9A585511089DDAC8DF1B1FDBE582ABD945E67F99ADC4452988 +A9859E39C90EF794C5C4E62997085B7A16A0D90107D08610BA175AD66377345662DA7DA4D8FEF847 +EE5D57E3AC54B928A0957CC1C944E7FF14658FE4A641CD26C61105C0F136A75950764B69CA17509E +3C19351D456B22C87C55E8DCC4ACD3E150D936333FF36499AD6B02B6403DE0F12901301ECB2EBA10 +324BA72B58206A13B8F37B0AEB12115D0C12879C8EA8A2EB70E85C95434564BA3DFF481C8972587E +FF74EEBBBAB14FB32B8A84B8FC42EBECA65D25E8C32C19CA5962832BF45DFDA4E871508AEC318495 +0D6DBE89019CEA29E40484C36E33D76B756255531ADD1DB24C03B2A64A47BD8FBA3FDCB1F5B96F8E +ECB60D5834AB001A70740498720AFB6EC03445CC35B51F7987109618C6C78CBE3041BEDC69B6FB12 +8142CEC5C8683B558AFE3024EFF7A12D04EF59A72E156DF11D33ABA08A8EEB16259DD9529CD003AD +4EF4137B6FF1654236473DFB93F597331A5E26C7796F528F65C94FE07B3B4F4DD49034FA0CC189DF +CDFF70C2F1C6D3DF30AE103E2AC5CFF20664AB934CE5C19693292071C93BD590383E0A1931E04D1D +DD18071DAFB628F5D7472E457BF81D6064EDFA8DEBFF91701C5038CB30865D6122076A336732DBCD +B0A625548773D0013648A76F07BBDC9C16284D158EC7A105AE37A62279419C3A2F360D0C7A74D6FD +D0E36DCA2A8BD59945A4196598F690878F84C894852C1811AFEA4BE3B9F6A5219E6628C66669DBD8 +FA9A0CFC2DDE7716A356FC4FB271D8A2CDDC8D4684DE447355BC7A287DC56852A638C5777826EB6E +B72FACCC86F80BEDDD0D649A883CFEEF4D74750172A90B5DD8252592FCFE19FFAAD868E99562DAEA +E70514F5DE296EF7B57E6F193737ABB6AA317956584423817E11664A67389197AD9F8F771EA59551 +98C9EE40A0761639E638CE9D890DF468642670235F1373D3AC6B1F43B5777FC0A91A96E095E89BB9 +FD62614DE456CE7AFD6B855112367573FD9FCBBD4A4F9C676E672D62DDD34A9BFE8311B6175A003C +D143C0DF15E4C0B48C735404086E48AEED6B6FA21FD9F40B84215DFF287F0677904E2DDFDA774A40 +19DF45CC877F553E95A1C65DF1D67BC0C60E0BBA4D205C0DA3DA80229FDD71859F65AD04506B308C +2B783839F31CFE4425263224F08C5C7E98A2C9D3DC8EA5AC1920F4E395413262E0836BC019A092A0 +DECA104EB2DF6B63392AE8E2136379140DE5FC98B0B69860FE8E31DAB5C5DF7807D19BEA34AC14E0 +ABC6F6519C51247B104DE7D912C5BF6EF11B48FC6DF84512E9F5FEBB48F72FF1B722BDC3BB2E835B +2E7CC6324BEE84893996B8DC2D4DC2793A4F69C18E63DAF04A7BB5C0A9076E2D5A343E134CC3C89C +4712900656FFC202E1988526D80C7FD9281FE47FBA8AB5D025E63A84051F6B13167BEC15B346212C +BD051AFE7A98BE3A2491F3C469718A58E783ED91F90E274FB4978F8719E92A99A1E8F142EA7E1F2C +46AFF0A2FB50F4D105130CE8EA309B0E480DC8F80D506172B609EA4BB4E2BBAE98D8882814FB273E +690DA990B60A9CDA20A2418246BD10AE67D846A0FA815AC25858145ADDA106A6778A11877FE59A2A +BE300D7DB9BBAB31CB5B960B7E4EF91D4600886D8795DC361CBDDDDE05EBD54B1941F426F7FA8399 +270D2F54C998BE92D146227270A8E89AF90C48BAFC4ECCCA01E6322AFC165743475E752F39BDAEC4 +9297290510FFA264342A0AFE2985F85DEEC66C36EB4A1D46683EE7C591A89B81569A8566AFBCA268 +10DDB0970577A76EC8A066622606B08315DB0F2E6C671F3259C73637D773D1A180AAD66ADADA2A65 +95B5F481E5F59E51CBA876FA06D21E1D674CFAB46A02D267E20234324D0891E7847C13C69BFCEEA3 +AC55F2EAF753726BCEB0DE1EECF42ADA964BF9E475953302C2FCA804B70B779482DC9319B40381E0 +9C0096460AE113C19A2DC9157FA138CF0E7758F71008E71D0F7599744D647B09B16E3C795C56EE5B +D14D8D63E7A512900D67487975EC9CEAEF69572FC3C2342AC5D365E8A4BCF462006B5268ECC15754 +94CAD9A9E7A9E8D9AFFE49AF647C017743EC7CFD5E66F4E4D845A6BBC836849274FBD270CBF263F1 +67DF7E26BA91F21C60F96257C07523AC37A2193010E976965CBD75751E312817C0564E1C5AE0CBA8 +BD12B01122D07020A0852120680985A8AC987BC33BE863EEC52AF13435B6E4048D951F5BCE36526E +07A8661CF2538F69D1F223BC53BF5896437D1BD46F57D9698F642F0E99C7392D8EE47134E34DCE94 +D392949B418D9821E12CAFA8337323E8469DAC24DADC6AAD4A0DADD7FF65694BA3A27964D28D8EB4 +1179458F91CD3F83B8F119BF5E76184DD29CC4C0718CF7945DCECC993A7A78739363136CEC7F2FB4 +95EEA8CEDB3EBF14373A058758C442939D36774435554851E9519B6F09C31EF26B6CD997DAFA11DA +91FA9759F17B7079164C5B47B99CCB7A876FBAB1D0D5D1E1A2683CD6914E6B3B755939CEF1C9168D +30B2738C4349650CF86C90D2542FC9B90F36A494C035A1C86DD716014AA16E6B9EC7AA03B16554BE +C436511DD3097FAB1FD0CD49EDAB96F74E8FD26400FC748CBD9EE1EEAEE24DA30DB6F8734B52818B +3A5E510AA5C14E42060898033E7E36CBA9A64042CF94A74E4B52E37AC027C0DC69BAC4944CCE12E7 +AD81AEDCE642EC34CA23E3FF07B8CD35DFF19F33C8D4DBB56A52534F8A827BE47AD4AEDCAD83B273 +38409FD1101C4DFF3F12D3DF79AD1FCE65B2F419451DD059C88BF066413E23DE27D3621DAC2DCC8F +9F3620DAD0F4B1A6E8C9E6E8ADB552E1EB2C4B2A3B73986AD53ED9ED8911F82F750DF05CD2EBA3E1 +B0DF208A87FB5ED44C3296B803881C1D9776D13350CD29C3F716F0B5A8B8557812024BA70069BE65 +89AA579EADB1F657712DF2570843D7C5FF7F4009D4D232D3547DC8B92ED5C4DB77B76255E661FF8B +163C6F3856DE5651B597EC7C78B84F0C6C1D6EA3A82286F1D3BB45F708D564E139E81F473C705AB2 +56346328DAA64D1EA8645DC10FD449092E0634D9D7344B2AEC3C75F6B6CD8B3F3867FF3CBB0F556B +186EE9A7C26BD2D17C8A773055D9D5013BD2F937D697A770C57BDB36D922CB911CD14E7FA14160BE +19C1A052E297B1A2D682D4BBC9F1D2493BCD7CAD2FA75D904C5F5479179DAF7DC6A4E0D269BACA2C +4F2430B4C8CF1572FBDC750A05DCD5B09FA3A9CD6F2F2A386E2B3D4D8E257BD43A783B38E63BCEE5 +03EA96FF2C373181744A607F0CB8D281D7DB1A6F4076AA3E2C61914BD796EF8A0873F79F964FDE28 +B792BA99A20C3F1F5ED1FD189FB1867C84DCD6AF43D49420C8B1F3DCE7DBAE71DEB17FE45644DB24 +4F44B1011C7C768EBB7254F4DACA64E9BA87AA7CD0F0C4B2228FFB9EBDCF3DDE4DCED39399FFEB34 +8811547D025320A88B480943A339E2CD2FA3605AAAE87939B1D7901465A1879BCB4C5BE1A179E7E3 +71F1BA2E0844F88AFBAE9B78DCCA47AE8AEDF5BD3D458C7D4A7A08ACCBF880D1F1DC69C636628DF1 +EBDC5C42FF88FF8B66351F3F72D703E52F3CE91E4E00759753A599FDD863788E99858498B66B93E5 +083BC3501C39A9BA928B0D763C28826FD237E949EF0BA85CCA9AA20C405DB6D5612DB718F7B4AD31 +D253AE306E4D7CB615C59AE668D347A4E60FFF7B103F8BD0E7CBDB142A763BE88AB40EEF6B8FC200 +458D728930AD0F94FE52ACBF0657C4907CC7942710AB1FD8BD149A9C9DEF6B8DCA7DB9062AA7B1B0 +11ABB5AAE8B77893A023F9EEEED4A20FBC30F922282A7AE2F1ACFF64151013D6B8AC2EAAE58171A1 +0F80BC18C3BBB5DE1E22EBE6033BF83040629023D74CCBAB3F1923CFA4A6735E1DFA8A1B261FBF1C +397E26F3BA9C2629CFDA84DFA3D1087EBB19DDA7E2D76E30DC2E15B8821D5291DA1DFD73940E5560 +A8A6DC91BE0075E3ED8D9E8CAC85AC20768D868CD2DC45DEADCC8B59AABE6EE5B2F891E0D7CBAE82 +0F83479332BF9707486698FE196C72EF72B52F54314329FC498171782BF160E1110A19B8208FC591 +EF0F0DA71AF657B43A7CC649A8488B759F7B69134B4F9DCF79DAEBC1CE52CC8015F324C9D46320F4 +4E1551EDA6D86139DFD1DB814CF38A22A89FABB4F75FB896B00E769820F763486E86668253CC466C +1529A5A924CC337C48448851A381DCEF63A0A302B65203D6571A1DD1FB9DC0C3BD6AEF4891497033 +109CEB5A481BFE442249940EC54096F1D0F2436D9E60495D0ACFF967A741B30467D24AC6B0032213 +18666B951EFD45324987B10BEF4AAA0FF1DF6887377A7F70F555DFB9FF1001C67438A167A00B05D2 +C37065655173A7ED9AE342DFA1497FB1F2FED6098901249A085D31B66DBB6AC25EF16C106B0A6FF3 +47CDF66434DC3F0012DAADE80B942D522CD59AF4C31C1C062157B3D000B9CB86E2AA7B4A5BF31605 +8A0D5A148EAA2C67977FAA0966E4C3454E08DF14C2498AD76E389AF65D2C139A6D8675298C46ACEB +7DBE6904C373C06E5F71399B2EDA0B40AB96E8BE991DDC39F92F1D24797F9EC9F2FAE25669B43754 +E2498E8EA5C44B176C3FB3E8F7A7A1481275A461F2549AFC4CC73E28417BD8C5212C13105EAB967D +AA679AE822B9B75B372A99C7E82D6BD83AA2BA00314DA4AC51B9CAA30D80507505BE24BAD0A87C5D +5D7336EDF60CCA4CEC8201D243C3932F74D171E2409D789AAD0D04A7BB22FB6DC3AB92AE33FFEA89 +7C484D741039F38C317EA396A0FBB9F15A27D87FCBE007558799BAB73212B6E5FAF2080BA074724E +AC87D88166DBC1464CF5D41B99428851FF1D99246944511CF42C3F9248513E9E51593F253D89C604 +388AD7132D6A169E9DD888E020AC1F8BA606F2E1EBB97977E505D8C40853653D8F398F71CC9F8F9C +540C22A1E6195BA578AE7262FC845FCCF77B33F33EEF266489AF8B81A615D6A13464BCA58BEC16C2 +3F31D678F14A938BEC31272DAC3CCB1B2DAE577A26BED852FC59843176A5FCFCFA0AB7FB00D2309D +E55C82CB9049F44FA61F1E313205A76317C4CF529A4456019D970624129681F46A9CD7950B8B5C40 +61853040113C8115319E68B37F88D864C6957DF813B305D09E6A1716B10F26F2EF5C727FC77AABBA +73E12B5AE6416AB19F6563CE14046B715BD4CB2B1E4D315F42D10F74CDEDE82BCDD524A1A5460921 +9084CF1CDABFE72CC8375478B41614BC18A914903596D6FC2F361EE519F875385F4ECB50F7053127 +4EBDEB14A5DBD906A60817246042E3799BB3AC647CDA7244B7998AE4F3BFBE5C767FD2142E48518A +4217599E0EC2CF5E86C8C270FF8B02F949EE001D6A439BCB4BC7D7F7C8167C3AE0A7E59687FB8BF6 +F37BEAA164541B8EAFD92E9D152E3FD0F413C99CCC34FCD8AA455A0B55DEC846A5874B94FC95CFF1 +BB386B2A1E22CD1C3914264B6D5BD1746972857C9235052D77A6C0DD3019F8A307FBEE63A3EF12B0 +39B224108276FFA84021F1AC5B745C54690B3FF587B4B1710AC3533A67BCEFC503ADF1F4B62B2910 +B31965E364EEC9CC437CC40181A7320CD52BE9C546B8F1DC824312216C2FD8232E2BB8D40EE2E314 +54C09772A387F9520E331456C269F51A078E6ABD9FB6A68BFD5F557215B0BBD2227B8959CBD1BD4A +EEAB094DD18E891C61FB00933C0A0D76174D169C0B6445D34C00DC9E06D85EB086C18F3BE27DF734 +EBB9CF078AFF6514438549CBE92A0C0D25EFE4A527D86F158B4E9D8870C7AC5D6C059643A3298079 +CC20398324CA87273B86ED801057D797D91BC3CF2F96C650EE1566CD3CF8656CC577D38B830201BE +718DC9A494268177A5019546EEEDBF101996BE593631654B638C75A6BAA648CD1E7AA9AC1EA60F4C +D604071C89DCCFF8B3E430A57ED6DE11C5837E78956ED991058F3646219BEAE94E4D9381A33D48CA +9B8FF12B54A73FF869D0EEED7E098D80152295E6016CDD809173C57D1F5FCE908A37010AD4C4471A +53451DE9B4363B63437C374C598F548F145D3D288F42531FCF36A9CDF72521F1C0868FCEEEB1857E +A983F6B75CE245D875BEAD1BCB8819E5464518E04717B78BD6E335F0AD77B832AF5682062A1E2AC7 +7CD5EDD5DC372EE456C96D38BF8BF348DAC2B4EBBB2440F2CE97B4B337F2E23247E3E8423BFA9237 +CA6CEB6FB93F960CAD894A96F0371168A33222052DE9B3BE04B022AB95C0C243486E35197721FC55 +311DC55F87BC72D09B6C940CA36E6640AEB66C394A5949A604E7F15DCE3A008BB41B0EEF2840A357 +F348443B4DCE064B4C15E5EC52E448C985FAA1C3D6526270B1CC691009959A7620C9A6202619A19B +E410FF7BD535A8B2640AAA459DFDCB8F2BB35112626497E8A397D4F9E04788322A738DC8907CB643 +15CF63C95809E90D06EF02F72AB04AA61FE02ECCF7E9049FF9F3EF2258A75656178AAAC9F3C2A26C +001341862D526CC14E92A81BD63502F959066E0BCD659CB9B5A45606153DD77039B8C5D5B13565F0 +0D95A41937CF97089F3938E39659A64DC3D6046D0E9EF66544CAF8A206635DF49926A3EEF3FDBC9D +CCEA2886EC855F1821C4B9CE1D02A19A11BBBEF43A7D4D536715548A62802F64AF30BBCBEA8C7E55 +AD56C801D8A569C8183615A78CD393CA42C103F155941E845712C335F4ACFC7807202B92A983111A +ED241BBB8501F15560E8F2157C29752BDCDB274008137277920053D6D7DCDC626A574A82A8A34F1E +77B2FC8CF7C1A7322F22DFCB450259EB450C52B70DF3584A7C54C813DB41E3DD81253A03B02BC252 +346AF0160716355797B6F8210C453DD7E1E756FF08C7E6A5F4F87605E1DFF35A130D79148A57B7AD +12D94A129FE3F055CF974EBA09A2B13DEECA2E02EA818A58B81E8743004646C7746110BC61B86ADF +2D5D8C45A6A5461EB34497FCCD09E711F47BFA742C73F87B257B53F30CB68D151424DC3C210D3E8A +C67C2495A8236EA2D7985A5E1DEAC699D7B700E6D38EEE2E93B191BAA5A8A2C916D206C63FE63427 +AAAFED2B5784276FC21EEFF2D70E47C8540DCCC3E00134642B703795CD3702631AE2A90E063A218B +61E5B89BBCFFF84F567E37A31A9B349717A8CDB9C9377215BA838FF7469BC486B64EF2B6D92519C0 +BF0826E3652903F40E400689F5749DF86FE3DE178E21E20EDF9053081F6510D8F19ACD021CBA481C +484D30EAD3B84ED0190087EE478A17154B243346C3938FDD5340CF6E47B185E64ABDF44F8CBCDB82 +94492B91929BFEB9DA2B033C3ACEE554F0F1A7F8A56DF7C06A3583C1E9C5CA458D40E550FDF3E2F2 +E7BE8312D5FEE98543388EDC8A04CA29F1B82B7AB4ADABBA3F2C331EFF3521B2B92F99C4377AB827 +A989B423750D36ADDD2E286E7F3B694E29B8BC403693C6F7CAB5FE34F1E48C8D41B47831E8C3F5BE +5ED5142E3C44ACF5180CD41FDA149B1F4AED36812E42BC184227F5034220F74F67830255E1CAEC12 +66DEFA358A87D2E3B4B4E7EF30181570D0B2B43072EE0311C2C157D32EE2BEA8EA4251B59F6B61D2 +B4FDEB654DEB67AA3DFF4AD65B727F0D6B7D61523E4B44D99BA5CD33540F340A35DDD466ABEA4E72 +E504FC9BAAE51D231C33A8CE7DC2970DE4C1FB5B096A3D9C641EF77DC9039886831DDD01C4F21E6E +168E38BBDDA5F4308C959C7BBF36A42D042DA6862937EB20D4FA2E5927741A58DA5CBFFD9553BEFF +BD92E6D64871D8B25D9049F4E71970A8FF5557D1DE83DD24286D6C3E4770EE00F9A1A0B0063C9999 +4AEC75E84D6F9C488434D1F3DCFD0A8BEE9ED8257CA97E75E8B1285747184D6D2228EF95D4A0B8DA +252318ABD35C8398FC6568B294D90AB308A7675F9F160140F0A08C88AD0CA1CA2CF85E4D031CFA3B +87635F1398EB7DBC666A259F02DB6741D13E11B230025DD6DD64C438409AF109090058151E4DFB8C +0E9CD65935C4CC063CC6100FDE70896E23E3661C7FC1B8228B26A55903E997F80207EDD8863FA074 +EE4FF23BE585BAF708040C9F8CFDEB42FB8EB71D4CB6D7757E973E4D8C9DDD082712C23F868E1135 +ECD91250BB4335958B07C12FDA75EEB56BE19D1644C1F76A8811C021122619F751CBBFEB1D3DC912 +999017FA163672A1EF754C5CB78962BAAB76EC48461B492FA88F9897170DE857CC8374C8BAE417D4 +C78A56047024731F4A45145F0393A27CAB614A7FF747BBC28E6880D4D01C0A6CF317A1DE5BB5ADFA +4B5FBFE0C57598C79F25AE57BB797A489D51F85A9B9CF8BEA64293F8FCC43B0D5484DF99DBE19152 +692CE756F6FBE8CE5831CF4B8A5AF47524E272C45C62ACBFBDFE7E60B05BB1A1A6AF0E9210012014 +69B3DBB49EC7B23A363FA68417B7118DCEA71D4ACA2E36F88C6DDEFB70205DF3AB7C74CF65CFD01F +F85FAF99F172689737331D4C6CFF7A29029772F487FBF625F17BDAD89B4AC076948277B4ED687840 +301016C2B7AD4C6D02F81E88C75B7A04D724E234E38A38269351582245E361A42C75B8256AFD5624 +B558ADA2190F960A896BBAE7A8C57E76DA10DC29E69BBF3AA86214C001A27B39C1D17C548DA5601E +86A5CF53E7B1896BF003AAE9387ABA9B102EB1E9002DD3754A378F3E49F2C6EECF47EB1BAC2CFCE1 +1AC0C5CB063672D32733563F3E1E891B6073739BC53AAA0043FC45E90E413DFBD4548DD320B681ED +70A7443A233D79E3F038D26975586E5CDD2115AA614727B1F6DD4024B85CCCFC79D10B7B6AFA789D +B37BD0E8C423C1A4A8681B5FF3A9FA1F61A46E46C4B1836D1AA41A89264A7F4B1C259E4B10ECDF37 +5BD26A1F412FE01FBDC03368FCAF48AA0EC28B1BD603A6A0D0DADE66D14C9B7285569230FAB76803 +35BE104305E4B748FA99FA31F23991608DFDD2097DA292551136F255051C9F7EEF3FB7C7FDB4E651 +C3D03A4CA357B587245236F4FF3252563F6BE08EF8A3EC09BE2BF27B9120F7D37801F6999EFB1C8A +D1A08698CC59CEAE2CFCDBF6BD8F94DEC94F7EBF33AF05F52C85760C63950B455510C6AB9398D09A +C288EFA09E8F631A59B03FBBC75BBDAFD675FFACCCF8ADF71E815A4A49F14BF70E42DB0B7347B528 +4E234C24010E2177DBBD57648E398FA6B54571A37BA8C989503594D03C6E60871A7F964599022154 +02BA168B8D1D2685F5CF8645D5E11A1769473027F42564C2966C10C0DEE1EE1B6975852A4870D492 +83A470E623337544A7CDA5C16FE2855BA2A548511FB4D4FF2E3E78D108E4C734F64EE2F12CC9562C +BDF363EFAF5201B673AD00583FF108AFF6B68055A5F299452D176EAAFB92C84F114C8C22A05EAD65 +64A3371420EA9E646308DE97D40705E1638DF08704FC90249CBC0D2D3E884A4562CC27370B1A9738 +9D8EFD237E644A7370B8B38ED1C377F522C75F981D878A5E87101E621DF9D85C7207BBE5A87CCB60 +7F93A2E52F660E05C83A7A6CE6D01AB4B62A1EF8DA47CF97D4BBA0FA8EFFA9C0F61A325A97ADA694 +45F23AB1FE27A66C271639F839203040D44B11ECC6E805FBE88843B34C4FD52D1D3C6C70FFED433F +C04501FC20536ABDFFA429B8DC8192B2D45DD9D646049CBF40719C3D674773F9676F9FCF32817DCB +55402A72C56D74AA4CE4035687C730B6B44A9CC614BCA5A3FD17C170ED949E588EE45E89E18B0766 +2A6327FB9E8475C43E5DA1B0AF07C23774B19C9EF59281F5D884990D6194170D8293A86DB52A0FE1 +7E88DA82209A00A16BD29B8B2F13FD60AA25FCFA9745F57C8216283C1D6EA1C119CB9B8D57C00419 +5210FFBD56395A3EC2D3098ED38F389EFC0324FD0E55EA339B3892568229D8D3E205A821E8219FCB +1A7713FCF3450F8BEF976CA0BECA47376A8CA73DF85B340C67EFE4534D459617996526B5E5D3D19E +17CC5449E5EF2B82B2C4C2131FF8A19FCFE6A186A9840D872D85C40665A7A04E67EE26B8BC9206C3 +5B44C8F8A1AFC3867D96DC6D48BD45063BE25B882E9BC0D0948C18DC870E6925818E1FE17D336217 +F174EB4481F5C0ED37A3BEAFAF4D46F857811B6728BEC461AE6468D87A736572F4FF95B58B04564A +9D3C22754587DF15495A319D822B838461764B73483C1F7CB930EECC6F7424841EE10E4087E95120 +2FE88A391375C96BEC4480328A54740213F741105B12A39F19808F3823507B88115D468C61B212A8 +ABAE7480E39BA52390A1892C7EC50271156B4E8076FC3ADA222695DF372385DA7B117A29E04CD2B8 +0A320F186D61C963FBDAFE9224E537057C49E82E405196AAB621B5FE4011E1782A747EF935ED8BB1 +1BDA39A141CC0BA42D04AE123383BC95A1D03A85A9440010C3B9613064FFECA76197E10919BA5006 +F35837ED9BCD7DE5E6D968AACB6FC91178091FA467EF6FDEB728E17293DC89DDE5A5261FAA95A2B0 +000FC750E7073900D4D88247DA464613ADC2B3903A6132D96AC0E1C564385FFBF6249DEA76BEA2A9 +9160632DD2FC2B99133E9F2F470F72B45D6F18B45020F604B06CD9174BA3805DB60EB9C5E6A9C789 +ACE76AE9C79C1BD34434E95E501BC968633AF93FF4883C6A596776254C0C74993710327086B2886B +02FD3E42A725A03459CB36EE34A094139AF5FCF487D3DFE63FAD20BF0DFB60DEEDA2ACCA3510E963 +189D1256EABD81253F7FF9D11263FDBC1DCFDA3D1EA2E52005CE3C605C993231258A717423F64BFE +EBC34684EFA676358B9B543C2042BEF954829FE3246A879845B30EBACB43D8DD7A20FCFEDF763AD2 +C5D20A798B69E08722DCE6A5762E249ACE3055B650D9E110599EA30DE5C4FE7200D5A8DA9E1FE268 +6350D0DF334877D0B9F6524C552D0B6DFFAE125EC4C18F7547BD51C14288E4ABB7F8A1A00458596C +390AEEE6FA308AC1F788FAE30D7F8928AFC91D4DE6352D20B19D8D8AB122B7378CB379C5BE7E3CE2 +922FE667EA057B5D7B3F0B51C7BF0C85F87AC2F360D82C38964F4DABCC9104B32F0FB8802235E8E8 +D9A5997D392259074C00AF2CE1D2BF7B8E90E2E2AC34185C68A03BAB8B267778292B227245D7FF86 +70786E3F746F86B9D4D17190DB859A0E144B2A61E6AC9254DE5DBAEF20E2E9DB0B2FF654B996E962 +F55E465DD238BD1643CE59DC2B5A58B1E6E4AE2DDC2D74D79AFF3C34E4E593E051FDA236B79CC0DB +268D2A89B1878051223BB8F33FF99BA87A4811C0B3BCC01171D0A731EB732ECD8749D27952C27886 +B252F9C3D190419FD2900987A0A255B9753FB7AA70C37462134C467A2C4B7920BED9F9E86F8F98B9 +6D00AF8B05A4BD5F14C2A0D914A9A84160D554FD0718F50ECB5DF5E76623065852DAA74C9AD6DA07 +A119DF12C3577FE276AE551D48B1C5CD8A50E84DEC9CB0840520D78FA7F9A7C2071E28CD20EC7649 +B991F3818CDE295CDB6085F24FCF93147E9F4DD084FBD32525326D2EA147ECD5B6C9D9F4A7166663 +AD18BF234E9CB92FF72138A8A49E73E527E9A6488A4CA808AECABC94D693CD2C0C357D285F65006F +A2F9197F61FBCA6EF07B013E2B558AB531D2FD270CEE7FA8E467FAB885E90C5884843AA08E2BBFEA +0AA575643727BA18ACC499FF34E3438645BE2AA71EA491E54687CD305E12BBC94FAEC848311AE816 +495B013BC5075A2D2AE54A7AD7C9105B64356CB51F18C2C28E3A83B9D81A4554DBEC9BEA9A660CF7 +E1BA89E6D4DFB3EEC6A3DE3FCDED9B2D614156EDAE8CFDAD5FF0EFEE31DA3E6A54D94CE9453A1CAA +D9756D91BE85315F6514BAFBC821EE810BB5D8E1B8F05F64F3F72C4B35D424F7E4DC3AB581B74ADE +B6D6297CDE7AA8278909F269FED79B7DFD39B1C0338E01D556C4DB9CA3A8578ACE3EC3D743ED4B9C +0145E4525E8C315F7A1B98584B975C70F0D415708C8CCC13F848B1D36AC8249B73638F95DE0CD27C +7EFB52BED4339EBDA4812564D7A77416DDF4CC88CFB52D07A252D89353C6826CA1832A153242979B +6CEE783ABDE65C8B40CF4EA7B42B8DBCC0E02423DD693108006F6A4AEBF053B666C3CB63D1861F86 +EAACD43BB9BB6F2C3A17293C189331D253B447757EE7CBF4518BABB73A1D44874D7F0625E6A013C6 +08E991B4AD17A9ADB36740D25E3E35B459B422F7370B134CDFFF3F3BCC4C32B4E9EBF6A2478013F6 +6933A1FA9403A2F1161EC632F1F04EDF95ED0F33DAD9665D54DD9DB2564E51DA7B65978CAB50D6DC +1568976E83B056EB0E3A6758518B6E17E9EBFE49B72EB148B472BA144BDC2AC95744C9BF1258F0A2 +E47470AB0EFF90E190A41108914AB8C1ED6B11E0681778521870E80C16AF2AFC723CAD8719ADB62D +3939D3BC8CC1D8A4E07E9D734F54ECA33D936D2C39D5C8055739C33E53359BD40E576C11E93B4B4C +122BDBC9B1BBF44243AF4F0BCDBDFADE68C526B5CD74E29CE3F70D62BA83C489034111FE8E4DAEA2 +F01F9D938ABB532DEEAC0E329F42453FF5C15DEC2AEA8C198323C9E8FEA55B3F5DC4751D2E2E16B6 +154E7F2ADD46860E9CA71DC114C99D80E7EA1DAB51E925DE161CEDD678EE6282AFF38E3CD0E65954 +9C970613209955A3F581E1ABE485E56402A3DB0D1E9B8A9DFD05C4B0B7F97FC6D0EED0B69AD6F182 +B1D028ADD2F24463834B13F5C1307F91D363891824E81108E57CFD5211F86400D3E96B107F3B1FE8 +9C4908649D04A46DC3CEE0DE66AF03A7FF9F4DAFECDD6DF4D93784CC899B527784DBE0718050FCE1 +85BDE3F39DEBCDD660B2488D23AB1CFF87B0546D02B48E7B7724C9E87B71BF34B5D6640E0F6ECE47 +B182D41C89461F712849C6CFDB7E3F5EBC1ACDD12D65A422BA362A8FD6CAAC5104CCC5AB5FC04A46 +E4309ACAC83D659DDDA256CCDDD1BFF9AB3622450C4FBC89C82214F00C42FB0311BCB1B722A691ED +839CAF9024FB1671F18E4639C96D84718C663A4341DEC037175C6BBD288BBF5A0478298CA726567A +9B74C32A527339C666A294A17F6821CBF243D13EA4B1603C292953308B566653423E7301A032E5D5 +E2B93F1C1434893633DD19501AD12728B5A1D9D36635B589FA2E151140B543D7C5E469AFAE8E80C4 +FC1D9CB6C3823CC1BB7EE40AECB58CBC1465792226B19E0FE79235115F6A3AFE19F98C5DB63D372D +D7C041CD940F4F79F2474D9CEEA0334FA04A97DC9773064895CF11CF73F11B4684F06E48F4469F6A +1AEB2CBBC52994DFAB3319DCE3A0C8C2EFA9627496F8CC84D3DF3BDC4FFCB61672780F294F453278 +AEB9262E66486856D37B7647141A82E049364ED3D03F925284A3F1FA3DDF4C0B48B3FE22E7DF9ABA +239D33CD300FFA8FD4B96192BD568FB18D325CAA8E1F1FD4B27527417B034841FD49E4A77F217062 +3CC8B22101166D80361EB15FA9020D24F61007B0A8274DF9DFCD8E97C85568E76D34AD5DB1779B02 +F034A69CCF9D4EBAA188EB3017EEF5B22A0A552696A574907F695098BD8A4849D5C8311F129447CD +7A3CF88B8191AEC0AFF30A38A9AB8135608A7829207A7D242F6E1FA7DDA19F5E4C28560D42DB4405 +77CC0C5F5803EEE897103ECA0BD944E320AC26553BEE7852EAA733BD13DF760056B2F5BD1243BEDA +BC3C1EA0531017D74B47E18F801A60074D6DF849FD0532234545E5B5E112D1E7385341D39A89551C +80DC2DEAED5D5DA2A4BE5015D297324E92BE64C68428132E6EC654DD4BDCC6640C68835FF8A05E09 +9604B8CD43D3AF2B2FE10C8AFEDEC5A70AF8509D12F662338CBF166D9452CD36331758AC4F4CBD7E +DD52139AD27DC52569877FE709F297444C4F31899D1945C81B14ABDECBF31DC463A4148F04EC4FB9 +703C158216C0FBE65CCD450043ABFD4E65BF8B28CC148252E9F3E797EA0B57B8721C94CBC2EA602D +F2C57E87938C887A382D2659226463BC7D6A1DA87F4A341A59BEA458177D3F18D1213539DC0E301F +6EFE0111FCF6921368BE17CCBB7428127E0C059C2C5ADB2A3F0197F0CEAB77FF7F3C027A8EC3EE76 +CF5C986EB47CB60561C773B3A2DA47B5A35394E29373DBD5C3FF4C9213A89AED77CC4F3FCFC49EF6 +EC7557C521979A546983C106B3627B5FD2D71CC5F08A32BF49332A89C5DA71AFBFB94C949A91220A +B1F885C981423AF93F73BC1CA4D92D9DBAE3EFE6A76E2DE3D0F74FD3255820636E3F1A6B7C185306 +23C12AF90CDCD2C0A728521E9B639EB6345D1DE8FFFC3B19C72E7A93823DFE3115E9E7BBBEB28CB7 +3DB121AED8920D47D8CC08EA2E472E39A4CAD5881B5C4204F2B732AF9D5189D25ABF413CC78714CB +01B1D8CA5565169A919DC481F6D2E67F1D490AEBC5CC62A8F62C1A323EBB55ED35AA5C8D6F8B970E +93205C2701CF4817BDA994FC16197B469ECC5F5E9DDF0FA05640C2E571849571CBD26402B1EB1E80 +3FCF423345007B9B52B13E3B034E8CB3984B925EBFFE719ED4F39F3D0E3343316A6FDC26BDBEA88C +4366D3B2F851D2B244CC4408251AE2C77348CCE9DD8BB9C89800B572D38C5D1CC34C740BEEBB5DDB +0A8BB251655FB989840D23205D16311A9FCCF7C85F6DFFEA9704492A4E7A8F6C0BDC29745AAC2ABF +AEBA02B0E7AEFEB92BA63AB0DF844EB09D505C3DFC1058CE42CDD8043B76398401E1DB862FF9F76C +05E8BC6260A4443CF494BC1755913D51745BF45ADF2F8C7A9546D7EF4FB11E9D94E4539632C2A396 +06D04480EE459408D7A2A869807A4C01881C1BB21C296A402B5E6E07093D833C3DFF075F4DD426EB +87B1B8DE16C146DE79F52F5943015331EEB852809CBB8E1D6460AC4D176FE96F8D19F6CCB22ABBBA +A27C4497D91312C3CFB5BB913B314E43D2EC6AB6897BA7C34CF2CAA6DB4BD69EB5DFCEE0AA917D69 +50E36A68A4C22A60DCC69379D47544A58D640EB10DFE120FCA843B588CA8B94F7869F97609A6FE03 +AC86EC1F7CEAD2EC8E81977D1B946E459DFCFEFE65A7BFF67E66F5F78A45D8DF65AF0146DF74E024 +FC042328886CC1DD7779F49CDBB750345CF83CD678A6A8897577299DEB38AD665DC4F21CE1892A18 +C256F318107DD3E9245C1AD3BC93CEF7B7BF057E33EC9A3F953251261AA3D1A8347261E70A46F777 +3A84F3D4D1A0DF6DD22A96429349DE0D180310E17955B10FBF53220EF6483D03C650A8D5C16D63DA +F65C21ADCD6C2D0B5D4ADEB2F5526AACF7CF42F9A8BF4832FB2D4F73F3D5FFD984B572232F87BD3E +59133ED3D2FA19F7856AD812515C74F7D851574019C532C25F8E163E595FC9C83E3E820C3CBF690D +A62578A980FC0803EB6DB9B1E90E3256BD4650816ABE5EA86CE65C2EB418D0ADDA5F3EA04E17AA8C +4536CC471AC20236E66ECA3619F161DFEFA485386C30EBB86A7AD930FD0AADF2DA69DCAF26C0F677 +206E2030E3B15B3662C0AD03DBC1636EBFAD1F2F2C37F5FA9856B0198C5B1D80B69C5EFFD94CE071 +5135C649C26B9BA1266B0A5B270CD08A706166C0B320915C87B27DE21DEB5D7E4806F6E700B7A06A +4E29B629CB40761983E9CA8E34E869ABD04DDA190BFE5A6EE8B22D7E511B84EA584A84211F27AF89 +18DC5AF8A1FF2D360B6BE3CA8E66BA4CD2CE6A25E7E89406684DA83FFBCCCCBFD0844FE3BECD7DE6 +7764C59C022DB1168D585FE25073FE00E30218D1DFE115CA1FC606AFCB04F2A082EF91788B6BD096 +84DEA31F20034A91AB9D971366F97B5009FEFBF1EF0AD941654081B1E8F0B2EA495069A1DDF11DC5 +6857D29533DC857958B49D1A0779732819FD22E437084BD9F3C4F2CDA4D12CA14431937AB63A03F9 +C040AF1D801F367ABDCA7302E18A9050D6026FBA5A5A7FAD44E31593173CDF277CD737D1CEF59FE9 +684252BC0DDD00A80E023B88222494C1C8C0884230AB11D1083225AFDCDBC1E24D4AD5FAB396D2E3 +70E44A7571B230660D510A5076D8E35F7DB72C0566DFC119EE1B8AC3C0406950A3C4A4DA36BDE297 +040A27F70753A87E6CD593DC6BE9962261A99AE5949340C5D45C94A9AA3DD636CE8B497BBB812345 +7C824F443A53B3EE595C38983FE3E07DBDC6ACD55CAE8BE1081AFD4857A5F52A3C925143507A3C37 +F1992CF72ED0D4C48D94AE6CADDC3BC87AC3A3EF035E02181F78449E4B063B0835E827644051551C +1603E2EAB5875F28FC77BEBA6923428D5521C698C6B7F133B0F689F105FDBAC30A8ED2F29F0255DD +F8A037B81F04EDF004CBE639C8DB0F94D0C5DB92D34D66C2FED66CF8B895AFC4E659D08388EA44EA +E83CE459E5BE306750A682B627802990037157339BF142BCB9C08FAFDC3C3FB16DC3544F62C6C7E3 +3E20CC4FC7CA21E2C3F6C546CD78DEE348F1A4C8CB548EF20C049678916771D83ACC9B7B22784AD8 +580134471A3C79BC86B5D6D0D305C32E6204274351C94F9DF45D9B2AD5B5087A89F90D6AA033E4B1 +D1BED022F36147C7ABD2B73134DFFD50907258E610C3B20949E141172B1C6A76DB238C375021CBA6 +645CDC26B717428B5A9B4D3F32A4B1E22FEFF3BB93FD889E1DEF8087718D5E3E650FE4A3330DA9C3 +7E9EB499DF5A342D8BA4C0A033C3347CB25A31BE143ECBF91384F2381E323E7FD3A82A3197C18905 +3200AE2C86B9D01AB0B289841EA7E9E9A26966E0DEF54DE0B85D8DF084B8C590081E444BAF1E1F60 +670FA12AB97159318624F2AF1B5EC7DD83C1073A99398D2143A52D10A13C201FB356BC9E90C63BB0 +BC2D4C42AF4A8B9C8C4D58A1B32E0597C63B3F8B3E893BD3BE8C60231838F1BC78E73A6C8CDD5E7F +2907F897FC8EE99BFFDA7338BCEFB5AEF950E5549ADFD207AEB15846B509FC57989883642498A381 +1B8E5CDE69C05924EFAEC232FA4CEF302EE3251366ECAEF57D25CFA3B4A9E6397D996F421C900BEB +CF73B038FE7B16FD0A1172AC2F40D19CE0B02FCEB8BC47DA5344CB933C7FEC950184F78ACB32D3E5 +E290E84BE753B9E7A7BFC4416CCF29D023760C06CDDEF2505806A65E1508990529245059AFD301DB +669D41BD72BF7A80A9DF66B876B3553FDF4DD38D15289AF7A1AFBC53FFFF135A6348DD784AB42A6C +0D6AA330B069607E2DF3CBEFCE79D6F63E274C9E73A33EB85246D5EBB986BFA923DF68B2B8CF82AF +6C33E785F35B25B1D1D614DE85A4F4510ADFE42D75B5FA5408A59ABE53859E28B3D000EB9C6A7D2F +67C91DD14C895BA87B9CB57B851E5193FCC2A443AF85FE28DF6F39537F23A058BCF81DD8C04CB2C2 +5040300F4C55975E856DCB4E21E2B5481BDCC05601942FB25BB8A6B6F93E2C2A33CD478B44655657 +C557EBB080179EE5D98C5CEBE0B25BFDD952FFEB258014D7A5BC4BCA4F1A23BBA73C454B12960451 +CE1752401B0151CB2E01D5C72595095EAE91D8D3BD55A54A2AEA89239FA176FA7CD6F16BB0733EF6 +CE6E77763A23AAC77DA88C8EFA7BBB2991E472FF2075FB25A75ACFA70A04C28764F4AE4C12051B25 +B120CAD2E3044DA35C1F94135DBD69B10DE147321CBBDC814CE99982AC1D76CE3D3330E41AB31F3C +76BF89B95EAB81AF3464C732D5B1411D97DB36C9063537F64756F205B16ED7058E2CB1D6946C00A1 +A0CDA9EBBE924BDA6C7D7B605C514A98133907B793C74CA858E82DA3519188CD974B34DAA74265DB +5BC8550D5F0B1173ACEB87458BCE2AB1F96996C811699A0FE4A9B849D39023725E2B1EE7E426D30A +6C5C75AE6BCEA6DB41E4EB2035F7F924E6B9F0DCD00EB2BB014222E55FE387FBF5B9B7C04F4688D5 +AE3529FDACB38B5EB0AF5C3A874C1AA6B17CDA8D1E22EEE05A3DA88449200D3D0D002DB86F6C51B3 +37C8E19F338E7BFA01E1202612D50E210140947D5F350E84F790286C3F679A5D7E43BCDC337265C2 +631527FD62D598B7CA1F5835C0441881B97F5197901ECDC4F195BC665A846823D2E41417373F8639 +567B228FE7B73D781F07A361AA49C3E9D80FE5B2A32C4C1E575D194E841967B08D10405FA44EEE28 +47DB9372C5CC931E50469532F1BAF577F680BAB4E30B7E1CFFA8574ABB679789F69A8A1BAC07B7C6 +4EF5CE5EB00E97B36FBEACA9BBA4A13B0293D34BDBC77AD1FF88E5744AF009823BC262511C4724DD +585E7E17D90F230F7A5861B0DFC42F0B4E49A04EE0EE4DADB908479DEF8372F334C53D2BA5D855CB +39DC7C9550F9D0F7F77E82D5A59FBBF34BFFE92DC9E6668B68FEEAA4F20053433D6749162BBAC5D0 +D428DCF2D58D49B127FA2E674EDC7D3613B1342F4D0ABD7F4C5B049FBF78E804D5F16505AE7EDCBF +4D6FA08D72890F5D55199034572AB4B0C9A7E7F6F5A403198864ADF113CAFF5BF9D4AB5B16F81D0F +C2188FC80875E10034D12E30C0364F8F72797F1AED525A2712A40D44210B813DF5A29C84E9F6D51B +1D60A5F6F938FAABF878D29E6AB252D95D05FC1ADF5D4CE1C9E585219112112BC6CD5C766411FBD2 +2731794B5DE0A27AC57D3C57926807469C360372BE529098C350EFE2154B87F1205A57A0B04C5206 +CC4FA66B8793BBBE492CC3271FB4F90A28D0066E0D7F63B8DD01549A05AFA5482C29560ABD628568 +75CAC16100087540162473498C14087B29B86B7BFAD693E81765CEC781F3FC80E9C7B410E9B55B88 +114191A1703C638DFBB469ED1DD8254B1407003A319CE74AD419B077F17047A01F0BC0AC8507191B +F72D77D9333C9DA8C9DA733EFB5305F49CB8C7BC451321ADD7D896395D269DCDFDD084EB3AA70338 +6C0697E962929651164135C094D9BB1C9B949D5EEBD3BB17F02C98C813CCBFB23C2C26218A2F4C63 +9A8B9DFF2C29406037F91938A5E1227310728428B56F48108CDEB33BD3191ECA89F947271983DB77 +6B2BC897A30EECF2601EE3B2A6F0E135397622AAC1F2DF523CE6E6BC720E13CB530CEF4AB9C8273B +D3D81563AC8A8E6C44A195112DAF824BC7A72FCDC4E129A480717BEB01085DEE65EE4344D0B41EC0 +BCDF842566B1D9F5353B1F6A063FFA6CDB06EF634C8BD5A7A63F991D178F56EACA653DD67685CE49 +E98C7554745A4AC533217662D23E1D6937135D13BC2208EB8D50560A2BAAC319DFAE478B6BA4CA5E +DA20222F0E9BDB0806320ED1665B54A347DE0C42E9F77842DE4D188E7E824EB2F0D7AD163F05480A +7FA99C5A603BBC5DBC843774CA66E889B945054C0ED0B1A4BB14324EF901B023C208CB95DFCE9284 +89789690CC45BAB97BE449F8E2F5AA9276C0571303E9788C46E7F789555BFCDC3FA9ED8DA8AD9BA4 +8B3AE09404664391E63A989EF1E24BB464043AA099E4F2D796E352EB277106D8D81BAF2F8562EF46 +BCFD1E0047E8018CBD973021DC1C1D821AF03F083F0B088A62EBCF2BF6C5B0FCFA441AAD1625FDB8 +34F943DD47A5A42EB3E9A5B49641F797C288B799A64897F1346070461B6D535E0C4ED099199C387A +3176AEDC7DA7E7D9E118E55565092A36F7C74ABF281720C0147F4E4F37D49436466C61FF12764E30 +43D8A6D027E70537164F0E7942F4ACA42BB2CB136177EF7197E76F49AB403F741C0EF902FEBC471A +D6C627424320A8C3A1F04C310C511B3F91C3937D9ACF459999C18A33F2C852EC38CA806599C728C5 +43714018C65E2C5F430F6270AF52AD71ED38813B60440779455F9529A4A1623CB9F5422B9216F9CD +BA913B9A1CD95DA225E254E8101216085020660509D03A034B5D7E32E3DB5E5962A9A27711D4C3E2 +9CD84057F7D0D7E8000947AFE896F8523253391D2E11FFFE523366B05C532D5629A90741EAB3D4A7 +31D3F6D4F03FF93233DDF88BB1913ABA22EB9AA6311E3144381DAE29BCC8639958EEE59ACCFA06F3 +5DCCC63E0609F542F3EE5DFB1CF718CA3F328455726F8F65E23ACD970E4049225998371B63E35AE9 +8DC54D8329B8DB0901FAA63129EDE21B158776981D4D094013C096E9CD020315D123C03DEBA21E97 +E4B584B4BC0AF25F5DCE53C2DC0F3E61F99BECAB40799478BE7F5AFD7F68E23EF50AD6645C967EE1 +1206B6E791769428ACDC370D64E4F2B3972E0E4F442297199350663D6E772FC6777A9B9DE215273D +082CCE4E8678FE9948DC8D5B0E459CD02F1645AC5620F3571A40B4D5A17DF5CFF48B6C843DDEAB5E +BF58FE13D7DA08E8AA7902119248B3B151DA583101CF80853B0150FE05BDEDBFB50A7FB0F65728C9 +3B9DF48CE8AF1DF1FAC25C1D58E1AD30274A00EB54CF2F16029E1AC0A0919C0655474B9A6936AEE0 +FB74BD185FE7D70BB84786997D34A40326A74356A4AFAEE67B6B26D1C1A7BCFF8697B55C816CCD77 +312C332A55315DC54F9BC0A0F12500E0A76B3936292A3DA2DDF5AA8CBB9B5DC32EDACC4827D684D2 +74E65B8B76FB2C2B19F7D5607523FA953E34BB39032C05B1C1244304606C55660D3CA8607E764EA5 +B03DB7FCAB5CF7788C6E60EC8C449BCAFD90BCABA4132B6CBCCFF16784FB59B36B77CF0A9EA572E4 +CA0A01C725A6CF2E4500CDDF5BACCB9094D48925434F044118CFDC2696AF5FC0CAB3884107ED17B9 +BDE0C0104B1292A1F8C99B06FC4A6360B24480BD59DF0488641899B0F42B1311B582717BA7ECFEE1 +4143654B5371C8B9B2D80685AD38D897AD1E64875C28C7020A84FBB3A3BBEE16617DCB9BC822B7C5 +9C5A18C0CF7E80163ADFB7AA03B7CDE8497C1697D90F2ED90F813095C5B91657FC294EF0E341DB33 +92ED860CB2E0AA09293D0F99AE9EB54C761CA2DB1E51E1CEAEAB276C7BD916C68510D72D9A67468B +09B3C39A7815628FB126CDFD5EFF59CC8184C0D35A5B5960F824BD175495DD3EB12A4E96008CB13B +8C5745303E66CF8608FF27C4709C1D854EB79608E52F068FEC0151A74C125EDEAEA555C198FC0802 +7BBBB802835E1D435077AE4B1CCDBF722354F6C572BEB1376D3E342195FA80AC9722EB2F46E44DE0 +5F5A227B731B8D4A4B6EDEF04AF2C5DEC2EEF8FF48C5B18710ADE3DBFA0C956505B6DA9CCB7CBB83 +4DB6CC754948855D833670FF0AC42A4773FEA8322BECEE04CA74AC2D66855132D11A51524488C547 +71B5B7A512796D7D7AE0F9C1FBC9CBDBA0831074F4D200349D0CA40537B92496692766F020AC43AC +01DB8B2AA2EFA9D21732BE3A315F6CAA402BB2E61D40DDEBDE11276D90C2C601A935C168BE600464 +76ADED15087D54A14C68EECBBBB590927C1E10D291C9285334CB0C80EDBD392BDE4D535EB61F8E76 +41F58AC1DF5B1C5A5D91E3E27E05CAF7EC97ECF0C85B6425197AA856521ED701E5AEB82A7F52A8BD +7DC97D5B3FB5C99A5DF84D1BAFF89072922509D76BC6EDB15CE5F9EB8F4154BEE1E82020240283BD +C83A8E49AA9A2649B7955D5C058F2818A63BD0BFE7EACED4A49063C489A626277AE1246F721C9926 +E2A2B6C31045FBCD235F3CC58BC4DD6C57FE998EBD1E9FA5154652BE3A1685BCD2EFAA079A3293F7 +8142A6473822FAB627927EACCD61B3E99C3077103D2D19382BC7EE15BAD0FDE489602D055A01DBBC +F91A566974559D1B477C209416887053169C3F8F59955BE4DE82B60558CC9AE15602A93F029F6B43 +29E0E62A03982DB32F5229714EFA1491A7B24AEFE18FEBC2C93DFE50B3F641B51BDD33DA38871BF5 +243C17502D00AEA2D9E9734E80A96788D4CF5BC12A42BC386162FC88A7435EE13200C1C2C6CCC5D2 +1A03941007B4C4291BDB711446CEAF27148104BB240357D5EDA0EA5A5CE27D4A83909D75BFC05D75 +F10AA74A6DE37D7DE15C1DDA3AC3045DA6CD48323D904E716B445E5E096FCB379353ED70CF4B6FAC +102C762711079EFAF13FB74C9B47AF75F3F6BDA2A4647D2AB47ECAB64DA6CC01479F618E8D2D0A36 +45445E8744683CBBC560D47C98078B84206E90EB839B02D37C852B8E284463D4E4D890203C3D5B20 +352110034EAD6BD7F41456B807E1DB1631A9D499E52E9D9853D86728B1A2E511F40F8CA1E4724A0D +17ECD640B52FF6C66E28693D89765FC391612E5889E77423EC85CBD0A038B6BA98B607701DC0C4B6 +6B3B28C7790A1F1EB8D051DC98276DD9CFEFAB3F65C1C928E48A060C992B392A43E56EAA6DED896D +EBCE71F8245BE4687F2F1B8FC0F43ECE8DB0BD0AB0811C5CE73CBE336023A0D66168B34A95B4B0A7 +50B3BF1D197E3C042C7914FA731D7831AF798E9429571CBB977E6258244E84701E5FF91D608F98FC +3D68A4EE5B81D5FF38B6C184F6118B875F022B4CE207DC7B37E1452DFDC591A3E506AE82C7E7BFF0 +011B0A3DBD616A993FBF878FB03B6C9F2055A2B095D29361F8253C2623653687FE0AB98078F6AEE5 +FC2C2BDE0405EABEDB3A33EB7F04CB6837176245F190C6BBBCD64522B12FE7F9CDCF201A1AA8A19A +7BBC4AC064B4958F44AA0F8DDA23835AD28A1FD0EA105DE2F395385DCCFBE2261DC5A89A23AF606A +3985E5038706B1FE0910400E16BF008F250F3BDE3AD806C735495D499F16F99275010478FD2127BF +7CEDD6B5BD505FBE9BD0065B4A7090C9D27CD5B36C3AD33E1B31EB6D44E375003B51B909DA50BD18 +218418B3CD22B43278B144BE78406EAF16C7DF6B6C1C6238004AAB73736B38E168441DC16F9A5CF6 +0793A18633BC43D78674D12D38CC979F7CAADA6EFE807CEA499CB9FE616496682A66E04BBDACE1DC +112B2156B9B0B20A58A8CB43FF0EEDB99805234B9A5789762AC7D65F5A319C33F4F7438CD15E06BB +80A7A97E976E8CEC23F4C646A5821880A82B2F1DC27767F090997E91488BFA15064B702F864FCE65 +05D6CEF87D2A0A12B55BA189AF269811E3B8B850C8401F3906C080D32618D9698A766732A40A9FC5 +A94E5BDDA3D028D823D6B603B6D17DD046DE181FD989EA0F80B4CA62F7973E4DF5E032A31FE6BC8F +5CDA678D4A72787EB8253EA5882C337CDF9AA3E1E7D9536DD09B047CD8962E773F72F6418A3AEF5A +289B3406C152A50CE7BD4B493FFFC27F6AA52F79EA67E362FD92559AA4F94A2F787F6C735DFADCF2 +F08AAF98B80C53CA5607A94F25F04AA65A70A75937840E73055B3D65FB054C63E2E48E68488C9315 +A13EE949E03E46723C11CC759D222CBFAD2E1A87CAD779B23D38F7E2F660DE1388EAF1CF4D18994D +75C6CC63F187FDB949940C18B537A0AFB12AC5F67B0283CA5EFE2E764C4369104B9D3B06490D1244 +C41D6085C85F1106082EC9DB84586230511C05C82412D2CDF3DAFBF4759A775628878F997415296B +C416AC8352A6C6988691FCB831CF95C10BAE691ADB3BA2918B35924BD5C3ACAD8B137397B10AF82B +479800FE16D472CD0CDBDAAB4F882A0649CF561004B8CB7CA32EC129D0A415BE6CB91DA2B65F44E8 +0D138808A127E851A7FCF927E99DAA0EA2D626B77A16C72E37F058A3B882FC4955DC8CB6312434BD +3BCED75780B13590BF4FE8D64ACF0371F9FB1D361B05025852AAB9EDA1A0C997CFA58052C454FD45 +1E6C1F194F4D363114E312F6DC35BBAF357A32CD200A3DD9654155134259887D677ACC44F89AA401 +CA27282DF7DC3F2F04A108CBEF2558DCCE28BAC2D87B8D5B7181EA927F61977764F882626D4AB338 +D95C9477C54E9C36012A3CFFBE199EC8120A99D2D70A21F9D9A0354E4EAC7947990E8A6E0601796A +AF6F14E758CABCABDFBD8204A8E748A3E5FEBA570D36E2BF474C0083229A63F96114182321B2EBE1 +BC76DD193724C4588C1D39D184C332FAEAF4C629F2B3B2F49996E46AA6C9F497428BEA52D58876B0 +DC07B460248BC85CC16773A5DAC36CDE8B152D96057F4EFAAF8B1DC10022038577368057699B3A37 +178A9F1F6C6CC60BAE820B7ADD0717911BD23A6DCDADAFA32473491AA80CFE90F2A77E24CE2826FF +77B18B869C33FA292FE01D6477765044C7D14A548B28B1360125C6933F05C58B0889390537CDD16F +8E967E0B38579449DFC1E07389B7069AA8594C5103465D5041CC929268DE863FADB6925B350AA94A +27D421FB7FCC81C6B35F906F12246B7A5140511A97211BA9BD6831A508E963FE8BE961332F557808 +488F06EAD75E86D60DE3FA2425AE8439ECB9112BC3E4D73747C1C8E87A649919827049832DB0BF6D +A8C85C9A2592AC002809070900ECAD52A56F1BFD456AFE066509694EAC075788456B0B0BDD7C192D +321E9FB6AADCAEF00F570F22CD4A5322FBCE8FA98FAEB681940895426270BB4319C11DA67D88552A +7373398AEC5DA7C9CAA9F3B34581C6E968DAAAB2751CC012199DD897B448986CFFBAE4D412BF9ECB +F46742715A9569932516259D3B3A5431CD7028E42FC751C434E2B714C718202BF02CAF9B8A2075DE +922322EA7CFA605C8376FA958B8FBE43031E1026FBE6126A3775F643EA67EBBD97F239FB3C435526 +75CD08B19CA5EBF53B40D728556B4481C7F73EC71CAB0F89E34D60C69B272FADC22E8E7BDC6210DB +09FDD913E209F49FD28E8712B8508904620250746CA3B21B026EDAE60A2822F59E912E626B93E0D2 +BFB3230DFD0E54E91A1DBA25A609B64D41ABD897A5D21764C351E85F9E87BEAB9E645149AD32AEEB +B3B1161032C701647115F98C1C2AAECE871862D91D321AB90F3E923B1FDEE00D927F897AA9812373 +6536E2E0700F10053D7E6C589BF66029D794883EAE4C8228941CE96565B50D48887B5314A2E55379 +59638222A6CA54C77CBABD460DAC11B063519AE4F50D93DE41763BA7CFBF4C7724360E750478EB62 +8921DAA065858341958E4F3EB5966C6DD77C05EEECDF4B5F6CF19AB507589B4219377959BD258EC9 +21C34FE1DB003F7D0FEA3E2FD6F5DDB0A2D62CA5A2CD3C7AB457DFF25094EFE04A9E1B9CE7AE3F30 +026B1CB039228D309A22899F6E9B9BFF922E117123347967D7C62C670E2C74579C35989925603022 +C17B1DCE378031ABC9B4B437C7B6E64620932E93189754C01D4B280B8B08699B2CA953AE4823BB9E +E34133C5C95B3290E1BF010705AD852C72BE87291E1034B09F44A95B6A2F83FEE8841DCF661770AF +44D0AC7F9CDB280939FC5D953D525E0B41B7BE188D5C794687330CD770D24D9CD53B895A253004E1 +8A31BE4E82B384 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndResource +/Times-Roman-iso1252 /Times-Roman ISO1252Encoding psp_definefont +/Times-Italic-iso1252 /Times-Italic ISO1252Encoding psp_definefont +/NimbusMonL-Regu-iso1252 /NimbusMonL-Regu ISO1252Encoding psp_definefont +/NimbusMonL-ReguObli-iso1252 /NimbusMonL-ReguObli ISO1252Encoding psp_definefont +295 271 moveto +0 0 0 setrgbcolor +/Symbol findfont 50 -50 matrix scale makefont setfont + +show +370 271 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<4D6F64696669636174696F6E> +show +659 271 moveto +<6475> +show +738 271 moveto +<66696368696572> +show +897 271 moveto +1 0 0 setrgbcolor +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<534D4553485F5352432F7372632F534D4553485F492F534D4553485F47656E5F692E6378782C> +show +1898 271 moveto +0 0 0 setrgbcolor + +show +370 331 moveto +<434F52424120> +show +543 331 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<706F7572206C652067E96EE97261746575722E> +show +294 433 moveto +/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont +<23696E636C7564652094534D4553485F4D6178456C656D656E74566F6C756D655F692E68787894> +show +294 476 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 520 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 564 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 608 moveto +<202020202020646F75626C65206C656E6774682C6D6178456C656D656E7473417265612C6D6178 +456C656D656E7473566F6C756D653B> +show +294 652 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 696 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 740 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 784 moveto +<2020202020202020656C73652069662028737472636D70286D794879702D> +show +1050 784 moveto +<3E4765744E616D652C> +show +1276 784 moveto +<944D6178456C656D656E74566F6C756D659429203D3D203029207B> +show +294 828 moveto +<20202020202020202020534D4553483A3A534D4553485F4D6178456C656D656E74566F6C756D65 +5F766172204D4556203D> +show +294 872 moveto +<202020202020202020202020202020202020534D4553483A3A534D4553485F4D6178456C656D65 +6E74566F6C756D653A3A5F6E6172726F7728206D7948797020293B> +show +294 916 moveto +<202020202020202020206D6178456C656D656E74566F6C756D65203D204D45562D> +show +1125 916 moveto +<3E4765744D6178456C656D656E74566F6C756D6528293B> +show +294 960 moveto +<20202020202020202020667072696E7466286465737446696C652C> +show +974 960 moveto +<9425665C6E942C6D6178456C656D656E74566F6C756D65> +show +1553 960 moveto +<293B> +show +294 1004 moveto +<20202020202020207D> +show +294 1048 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 1092 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 1136 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 1180 moveto +<202020202020646F75626C65206C656E6774682C6D6178456C656D656E7473417265612C6D6178 +456C656D656E7473566F6C756D653B> +show +294 1224 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 1268 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 1312 moveto +<20202020202020202020202020202020202E202020202020202020202020202020202020202020 +20202020202020202020202020202E> +show +294 1356 moveto +<2020202020202020202020656C73652069662028737472636D7028614C696E65> +show +1100 1356 moveto +<2C> +show +1125 1356 moveto +<944D6178456C656D656E74566F6C756D659429203D3D203029207B> +show +294 1400 moveto +<2020202020202020534D4553483A3A534D4553485F4879706F7468657369735F766172206D7948 +7970203D> +show +294 1444 moveto +<2020202020202020202020202020202020746869732D> +show +848 1444 moveto +<3E4372656174654879706F74686573697328614C696E652C73747564794964293B> +show +294 1488 moveto +<2020202020202020534D4553483A3A534D4553485F4D6178456C656D656E74566F6C756D655F76 +6172204D4556203D> +show +294 1531 moveto +<202020202020202020202020202020202020534D4553483A3A534D4553485F4D6178456C656D65 +6E74566F6C756D653A3A5F6E6172726F7728206D7948797020293B> +show +294 1575 moveto +<2020202020202020667363616E66286C6F616446696C652C942573942C614C696E65293B> +show +294 1619 moveto +<20202020202020206D6178456C656D656E74566F6C756D65203D2061746F6628614C696E65293B> +show +294 1663 moveto +<20202020202020204D45562D> +show +596 1663 moveto +<3E5365744D6178456C656D656E74566F6C756D6528> +show +1125 1663 moveto +<6D6178456C656D656E74566F6C756D65> +show +1528 1663 moveto +<293B> +show +294 1707 moveto +<2020202020202020737472696E6720696F72537472696E67203D20> +show +974 1707 moveto +/NimbusMonL-ReguObli-iso1252 findfont 42 -42 matrix scale makefont setfont +<6F7262> +show +1049 1707 moveto +<2D> +show +1074 1707 moveto +<3E6F626A656374> +show +1250 1707 moveto +/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont +<746F5F737472696E67284D4556293B> +show +294 1751 moveto +<2020202020202020737072696E7466286F626A65637449642C> +show +924 1751 moveto +<942564942C4D45562D> +show +1150 1751 moveto +<3E47657449642829293B> +show +294 1795 moveto +<2020202020202020534D455348436F7262614F626A5B737472696E6728> +show +1024 1795 moveto +<944879706F5F94> +show +1200 1795 moveto +<292B737472696E67286F626A6563744964295D203D20696F72537472696E673B> +show +294 1839 moveto +<2020202020202020> +show +495 1839 moveto +<7D> +show +295 1956 moveto +/Symbol findfont 50 -50 matrix scale makefont setfont + +show +370 1956 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<4D6F64696669636174696F6E20646573206669636869657273> +show +370 2015 moveto +1 0 0 setrgbcolor +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<534D4553485F5352432F7372632F4472697665724D45442F4472697665724D45445F575F534D44 +535F4D6573682E63787820> +show +1672 2015 moveto +0 0 0 setrgbcolor +<6574> +show +370 2070 moveto +1 0 0 setrgbcolor +<534D4553485F5352432F7372632F4472697665724D45442F4472697665724D45445F575F534D45 +534844535F4D6573682E63787820> +show +1764 2070 moveto +0 0 0 setrgbcolor +<706F7572206C27E96372697475726520E0> +show +370 2125 moveto +<74726176657273> +show +551 2125 moveto +<6C65> +show +627 2125 moveto +<647269766572> +show +789 2125 moveto +<4D4544> +show +937 2125 moveto +<64616E73> +show +1072 2125 moveto +<6C61> +show +1150 2125 moveto +<737472756374757265> +show +1370 2125 moveto +<6465> +show +1458 2125 moveto +<646F6E6EE965> +show +1642 2125 moveto +<534D4453> +show +1809 2125 moveto +<6574> +show +1885 2125 moveto +<534D4553484453> +show +370 2180 moveto +<726573706563746976656D656E742028636573207374727563747572657320736F6E7420696E74 +65726E6573206175206D6F64756C6520534D455348292E> +show +294 2282 moveto +/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont +<202020202020636173652034> +show +596 2282 moveto +<20> +show +621 2282 moveto +<3A> +show +294 2326 moveto +<2020202020202020656C656D5F49645B375D2E707573685F6261636B28656C656D2D> +show +1150 2326 moveto +<3E47657449442829293B> +show +294 2370 moveto +<20202020202020206E6D61696C6C65735B375D2B2B3B> +show +294 2414 moveto +<2020202020202020627265616B3B> +show +294 2458 moveto +<2020202020207D> +show +295 2575 moveto +/Symbol findfont 50 -50 matrix scale makefont setfont + +show +370 2575 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<4D6F64696669636174696F6E2064752066696368696572> +show +370 2634 moveto +1 0 0 setrgbcolor +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<534D4553485F5352432F7372632F4472697665724D45442F4472697665724D45445F525F534D44 +535F4D6573682E637878> +show +1712 2634 moveto +0 0 0 setrgbcolor +<706F7572> +show +1838 2634 moveto +<6C61> +show +1909 2634 moveto +<6C656374757265> +show +2080 2634 moveto + +show +370 2689 moveto +<74726176657273206C6520647269766572204D454420737572206C612073747275637475726520 +646520646F6E6EE965206475206D61696C6C61676520534D44532E> +show +280 399 1 1451 rectfill +2125 399 1 1451 rectfill +280 399 1846 1 rectfill +280 1849 1846 1 rectfill +280 2248 1 220 rectfill +2125 2248 1 220 rectfill +280 2248 1846 1 rectfill +280 2467 1846 1 rectfill +showpage +grestore grestore +%%PageTrailer + +%%Page: 5 5 +%%PageBoundingBox: 18 18 577 824 +%%BeginSetup +% +%%EndSetup +%%BeginPageSetup +% +gsave +[0.24 0 0 -0.24 18 824] concat +gsave +%%EndPageSetup +%%BeginResource: font NimbusMonL-Regu +%!PS-AdobeFont-1.0: NimbusMonL-Regu 1.05 +%%CreationDate: Wed Dec 22 1999 +% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development +% (URW)++,Copyright 1999 by (URW)++ Design & Development +% See the file PUBLIC (Aladdin Free Public License) for license conditions. +% As a special exception, permission is granted to include this font +% program in a Postscript or PDF file that consists of a document that +% contains text to be displayed or printed using this font, regardless +% of the conditions or license applying to the document itself. +12 dict begin +/FontInfo 10 dict dup begin +/version (1.05) readonly def +/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def +/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def +/FullName (Nimbus Mono L Regular) readonly def +/FamilyName (Nimbus Mono L) readonly def +/Weight (Regular) readonly def +/ItalicAngle 0.0 def +/isFixedPitch false def +/UnderlinePosition -100 def +/UnderlineThickness 50 def +end readonly def +/FontName /NimbusMonL-Regu def +/PaintType 0 def +/WMode 0 def +/FontBBox {-12 -237 650 811} readonly def +/FontType 1 def +/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def +/Encoding StandardEncoding def +/UniqueID 5020945 def +currentdict end +currentfile eexec +E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89 +699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641 +2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2 +5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF +9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A2261C63C769D2F4B60FA2C438AD7D199D8E4 +5F7E7C9A605C8CA14E21FCD81C9A515FB8DB6F99604534D06EA9D87FE0FAA852899C9D0595C7A97E +6C55F79FAC45CD38E87B10D210CE7501E88C8FCD3444354365FB893A12F596AE2C1E70D5819EE0D0 +87D10BF8DA96F3DABD5405D28C4228C6C31BA4052464859640933FEEFD8071C0C84CDD829A9B1D0B +A01F25A4D50EE2EA2B45160CA6333B2D2800306ED2BEFDFE155E9D9F9342EB8D5B0ADBF2460CCC98 +643FB1287CCD28ABA7B5CAB92EC39EE2E918990372B16F8487EBA30EAE88708B6CF33B6C015D8096 +C7CFE2F139F52052E3925C0D50FD64CE68236D59CB83EF56BFC584150EC38065059F3308AD6F9A99 +F83EF4E6CB13855C8175E31417D190D036B387D3952344A950F4D8C7781B307A094DF1ECAEE4D2C2 +FD747BC6F7F9C6BD0E90C19294F96C8C5CFE88FB34C477574A1B1630B8CC591529E59B20794DA32E +61DECDA8ABBD1AE956CF74012AA01D42EE01E861B0AA6897C864788AE59DEF43C493246FDB1ACA55 +4C12594BC7B33657A9ECC9E3D1472EF826073F632BE540C35FF6FB40566773F3BB2204D3A579A08C +CBC844C14B18C350F003B9DA23A570C362D6003893CA32F86F59B829C78EE3188B6E3F7FA81D7F62 +2825C639638DFB78B7AF1F500F5B450FA54DBFA5CBA277C794ECE93275A3DE0B452FDC8DDC2993BA +A42F28A636008CDCB03EBF71BDCAF35019778993443F88412AD2AD0D7155A3944606463266322DBC +0244B07DA1E9C27A27B59664E8566D7A54CC03E995AAD008B0A17E2C3EF61F720CE7F7788599C4E4 +4C709CD5C31B11107F16AD70B17B9AFE2E8CD922A7428DAC171427FFAF51067307FAB0ADB530E701 +FD22DA22C4CD3064067BD4F6089C4B2C87937DD426E4E9D2F60E608288BAC9056554D04947E69200 +61E379CF5E81BFD32FD37EFAC1F61CEBEE551B0851516471A7472C60DF89DAA9EB1DC5A67E479745 +3E69B9E22BAF4E3CCA4192D603295B018C4AB69D18DE52DFDF15E96B557F290A4B8C5B1E7A6CACA8 +1F2351B97ADFC36995ABA43803A6E5AC04A3C93495F6D38106B8B144449C07D1358210F9176E1565 +72363CFBDE576BFDF99FA329DD1346E83F79E06CF68250CA57A68931BC7F342AD295D0CBA17AA95B +B8EEB53EA6E8E660B814E9F857CECB14F44A43288B69A9E7908D55BF19E844359879D28CAEF1C38A +36420185D20DFB32C2E002202800E8EF3D67C5D50E919657CA958B538D537D503444865331D79BFC +40312068D72364503BD0CC84B5F30A74D8B5B6A26AF2DB764564FB65A6BA8F9051AE2B4EA458D46A +4569F30C6E77DC097356770362E6CF3F1661074778EBB44FF7D1E3B64FF75E77E11FE525BB121C65 +46CFD13300CA1F02D571B82A5825E6226D14FDCF27F06D87452A8B6C5DCA658535CEE2A795E58137 +D48E566B69D53A0C3B766E84C51EAA221C46999CC8065ADB2F129D5B630FAB1814C0C33B5AEA0EFB +B6E994D80941B53079AF96D90A0B924F9B0E319BED9836B8F9053F868363D3CA554CBB181863301F +8CB940872ED5FA7BD18CE39218B5AD8AC57D0F752D941076B1C64D99BE0DB86D7A6D96510D772EB2 +4C587F11779BD21CFE5BDE1F29C1EF9022B2B8BCD7F91153C845906722477829C40111D810480F3C +F62DE8DBA7FD86CD236E656618CAF6FC46827FBC4898EA7672F8C9971AFE43E0E01EC8B77D4AF48C +BF1210E98C1DB15C16D149BFF58AB0270CF015B107A3A50F5DC8F37FFB92EEC8CB6778DDB7CE4AAB +C464C4AFF654223006A550EB52485A23D2B4AA7198D3CD54418102F1E9A4FBDE37B841E56F5C2C53 +966DB9B66B000E4588282E3FB80C2C519339F0002D2F83C979EDC5827A3B3C8EF8810A0F9DACB6B9 +998E9AF6551F56313DC4011904CB979AA2D32B11A811BC248141E4B9734D9FB7982A5671002D8279 +CAB93ABE057474628DEFC95D43890DB1ED34CFA8A20BDC3D874E7679A396158E522ED0AB969A4E3E +C7E4474E192590504D54DEB7B260B7935C4E56548A7D121AC1F741F8CDF259EA1B5813175A77A1D2 +D30BA26F65EB765A04C09ED51F69F41551ADF399E6AA2FC09788137BEA4913F17B8EB838C38FB272 +1FDCB55FD65697FF0B850E7D3D1CE266BF90F7EC06A9A0876BDFE767D3A918B092FC78C775F945CF +1F96E859C03DBF630D9A940939654C3549D8F7921CB94EE23D5A0535DE9DF31EA0F937F860B4F220 +A99ADDFC343D7CF7BFA0B803C12C26403F0DCFFC8EA786D0D8A8D9C367419CA8AE41190CE93A8086 +583A1E6C9D70B612C84D87D2EEAA71EC2DC12F4CDE6A821303D5F6A9BBDB7EEDCD289E80FA3B75F4 +7F481B50719DCF4A142069393593B9AF9CCEEAEC56A35B8787193D7C88113E9E1E221D151E093B01 +9EF89F6118BEC4735103CC8003CC5AD1B6727B3226CD44C497DA7052DD681695DBEC3397F9598C91 +77701C73BF0594CE93F23D50EC5BEE2FB9DA1FC966DF148B27B28EE3C89526DD6625E2887F9FA076 +7C127C609EE315626BC14D274FBEA56528DC06A27B2D476D46E9E7916590B156A5DF04A6CB15E362 +45D77021767B6E5BDFCC679670263FD891446C3371B11BB6E1DF60F960AAB4149D7753E6A5C33810 +C42C8BFF4E935003388506F8278BD7CB672F132E065AE684DCA0B9064D01DD620E7FFDFE04F14277 +EFE8E60159BA0FCA3FE2F28B902D4AC275D19F0AC6971EBE827C4A232D87650D2688345BCA78F879 +077114F0463C5F058107B669566F8171E4E284D278405580F04BFFC9902784216E0C9A17AA9B2935 +E66E18A783F723BE044389B7E9D62AA36818FF2EA406C3C1A9D2F3436F3EE7DB8BE86AFA8DAA6A4B +1B84611350D8D27605509612B515E16AA843164D5D0805E36A2B9EF74C5F6A0B9D59A04B55697123 +27F4B1B30E9587CD103337639967CBDC655AA46E80D2CFD24BEB50815B5338E522B3A7AFE8362AB4 +F05D8BC52BBA9C5089ADA8C89529B0275AF422EB540D31A938B8740860756325B966B36817115213 +FAAF92DE63F6BAE1E0064BFBC5588098B61EB83C71F1C2082436D37DAF1ACBE186FEDC4BE7C1233B +6F18BEC5F99002D21CB7864E4811F7AB3C03003E1E4490AD1AC793BD28FCD5EF0E6CC30EF39A08C5 +2F71939B0CEF620DC69E31E39D6DB969049031B0C92EF2DB653D97F370141456A52985076B268652 +FA2648C792780BAD637C4D7581FB2D62011D57E293719487CF2D1F013CFAA532E1C2D39178D51272 +A6AF041440BCA174B5CC902BD7390C7D3695056CB4BD7791F9FB6D88E7A70DEF2C97869F5DBC5BD8 +23C517C7B7C39D624DF627DC9653EA5347BFDA80B723F05F6DBB4C9EA501D862ACE05B9DBDF21B70 +56FBCD8C6D4B85873DCEE6166C8B5ADC0316CA12D9639F361B15A42F00E1D62EDBCA1111972FA0F4 +5758BECB31DB38316F3CDFE1B41748C93ED58B67E9B57ABBED5924A6D53E99FBC9A994A6489A8BDF +13EB685548B4DC6D62DA7426C22227D4D43B6FFC7B5EA91C896730253E8941AFEE588359C2BECF6F +FC415B9EB6D31CCB0F6C7F85853E6449FA6D627A97A3CE8303F148393ADCCCDFA2FE085C6908BE5C +3C05AF00A6F02840206C3253A559AC5C049BDDFD11AD9B118403B84DA10AE3C470CB9A9A2D1D7B73 +2F59F5FE146DEDA60AE750F551AAC934621B4470E1BC324C436303E25F81D0DC3188BE0D6FEC5414 +C20E4CB18952E12CB6423DF7124627ACDE145500D77A97A8BFD9CB50D1FAA008E2CE2B2505A4749F +1EBBB092C347023714055A9B63353AF9E7FEE05BB54C9843698101F79888A91531773830C2C967B5 +88D3ACD2192883D5CE3962D51084FC653EAE2C5FB2DA41DACEFB5C76812D2EDB5B109677289CD199 +8D457FB1023A19AC67295BBC1A9A20A426B06A368DF3C5DD083CB1180D287F5500F2C635EDE157EE +FCEEC5503447382D15C748C1E35F68753992E5C90F900DE54D18F8E1B355D1076ADFB1F3590135FA +D1A36F028E44F48ABB149B80CA9A54614D467F8D71CB310BBC7AC7100261092DB8C5BFD39E0AC6BC +2C9D6CBC3A8C05FF8A74CB21608EC4A4CFE4CBAA2D056DBA14206106044DECF59F957EF8A9CADE4C +9B19D8D30DD4FDE6A9548E50DB51ACA73330142153FC36B69C1C8D5B26D0C689B7040E81AC2C864F +D7C097C99BE5953843E172C97AB5684F35FB03A725A89DBF371F08DDF40A1531FC1B676DB0E1543A +EC6E97D3D2E4AA3D5831D8B3C952ABBFA112352814FB6FAB61A0D680E6640F6AEC8426200CF61286 +F7422CB2F78C61EBAA36D47EC16D7FAF8B4AF31D090CDFA255D9D7C61D46CFB22A7D6E1758E71ED5 +67E00CBD8E8F468DDFB477F091A2F915627F22FF47B876544BC1F03B6BBB98385F009C20BB1AA2A7 +A78674692B8EAC2E3C8069B79E679338DA57F72976810F845BEB6B9ADD32B95D78E5E60F16DD1668 +9C05FD82D36A3115BE8ED494A74DD211D58A2CDF983FCB9CDC29BF7F0E29988FA23560EDF514BC1D +183F3B2A22C09FB179B47E05ADEF48DF02F31C29875D1915037B19407764A4292FE44E741651A8E3 +BEB5F0D972B6327090F664417C84F84FFBF0AFFF8B1D85C822D90730AB4140C42A51AA8B1DBE4398 +4EA8566040EB8B341CCE23FD3F69DD235A080BA5C69AECB9BC732BC2D7D40617DDA6B79FB6EE40C3 +556C7DF9B23DAD89E94054B1345DB8402AE679FC4655A4A776C0150463F8DB2BFC0608EA1F124E22 +1DDAE6026B5E5D007A7E4A0D6B3B0CF3A2669E67C5E4F01551966A7BC48F2F4B6A87E740D8095E63 +F77C7A027F26B52F2299DE5B8A2F6209BCF3D31CB0235F998F781E5CC81E31DC424E008D46EC0920 +2951E5684804A0592EA47D6C788A20487BEA2EC8F2E6C1D7F378B62DB43CA43C4B366F8B4319631C +FE9854F0E10321CFA3B01C873584863BBEFC23C72C05E695B56E8A52E89AA2DAB543834D34DCAC5F +ED08DC51825C5257AE59850D101D84F4CAA1D29FC932F9E0EFFBF7A9A7F3685F61F0490CD3CC8988 +2DB52A757A6AF4C4E67B407BD2316B1C0FFE7DC54E43C87B874F57E4903334E2140B011484863CDC +ACA331175F2CF3D72E0042855983AAF8853D3015E870FF0807014C31D55060DF3FE1FCE157324481 +2744AB51322444632F9AFDA6706E320FFE82B8CBE242A19DF00CE73EE48E25FF49D5871BD3E60652 +298FE3E8D400609E232E0DDC794C0579ACEF89E841B2EDCA50D51151F65E8C1CC3B01EF1870558F0 +BF5743718C3E068617E81BFE120C6CA16E0924BFC2541177D53671CAA3AB641C41557DCDAE1A3461 +47B5E999C4541B08B4AFCBC187AFD653D5B5F8386DF6AD8FE69E21BD0567DF494F736C6A184FA4DE +48DC9F347787CA96E2E00A296C2DA05C2AD9BC423E9CA428D7F1FA12DC9353A302FB8C529AF8688C +BB543B45B2717EBF8F6C497935F4F3BFFD285E0402AB7544B3CA4643AE5A8B5250ED987A95FC1F27 +5B9707ACD0641BD0EE2AE9758494F8D8A51DCE408A38AC20EAF0852D72D84D0C6BE973326793AEB9 +55EAC6FE0A2813A355DCD22F6F2CE56588D1C055CDDFA98878BCEB6A018DB22922D2B600A20F8184 +2E665DF41013CA0947C4237C2BD60A75E2FD1A3FB8C8FA19485730B87461AD466ACB02DF8CA24091 +4FB090B3D2B41EB6B8FF05E1A59D9FD668AF70BA5BB72778953BA55FC5F9F626043450E1D09BC83D +8605098ABEF884639A37809A32565CBEFB3FF39EE53D6C18C58C272BB928E4410E361E59A50F242D +69747A032617C52DEBBF62364AB5A96EFAF642D9D82BA679B1D70FAC10A4EB62FA5CFC308E86368A +AAD7E75948F43598CD1C544A0D4091374D7E88D4522CBE902391641327E888E7748FA889DCE67ADE +61699E7D77763681CAEE9B1CA8837B2F7EF9C18CBCC538C465C8E2DD34616953CCB6030A222C728B +834911C1A179E2C770289407AB28B303E724D97F747D6134B425216A64C6E0B60F633E2B85300047 +E4C90339CE030A0FAE31E830C8ABA5AB3386A3B69267351A7BFDD66356AE5E57FB2994452993E90D +E7C4E260ABAB93C37831856A650D56E44172FECA01D6C7C380F250B82473960D2A2A5FB6B4DA668F +46E624ACF7FA0FD4490F485D640A3ADFC9F8652E7A38CE5799F770C3606DB4B8B947F93967F779E3 +A3C0572F13A5A187D31D7BD12A5C7BE23CB6ED6192086241B76C5BA6983DB9C93E4B208D707D3760 +F03CD6272EF3A4CE89B8E52E6AC5871A3D03EB975759AB4BE239E5EC7842CBB333E692CC607C722E +185D3C39164DD320C6945629C70FF66A5237C0A9520A1FAD6EB9816069351AB0F135D90CC0982B14 +7D2294AE4A38A527EE40BE9CDE2512AAEBB590E134388BB171D0956A7C4566D65A9A041BE6C4F883 +6B3EC3D2ED1B48B566A783292B15B6127920D247D494F070BB20BEFF60640B11B276DDEEE49706E8 +B2B21BB40B7F00AAFC594C492C25DCA774E0B80D82E927448DE2E74A9D0DC7AC9260096EAF187B6C +D6AEAA6D1DC4205B4411122751A5B22688404EA7C5861730371FFAC10F5AFD4727A0E402AB5EA757 +606B75EB86A05E8F774D6E430A1A3FE2A37EBB06700474239FB1CFA05EE44B91B82244C575B52E7F +AF934B04EEB0D933FEB57EBE326D75821C8B23EAA85B583AED4320B7F04B9F2DC591091216FDE52E +064BAAA9C2C9D9714B95A4558C21F3CEBE624B5403B31508F178581AF6863083ED762F1E2E34A45C +FDD71660D626FF8648F5D6C5E580D4765A67FB6159EC8077A9F0A88038C8D3D7C77FF0926E2123BE +874F7BCAF129D55A5B5960F824BD1728ABCFCC51D23936DE9A25C408D786E44C3A2BAFA4423177AD +060D21D38E15E23EB6FFC0B4120E814695D423EEFC2744A1FC81B4DF89D76F0A6803D8B14E75538C +AAD03A72517B86514F6952F6FD619D9E910D980F00964DB325318C045BDF79647F453D4A5CF4E61D +D5359782827229310405FBCF6107C3AD9DDEF9A9A339D5D5A6EB2E7838A0A43221BD62CBDF732DB0 +A638A52016FB35BA7761AEC846A023D3BF2D1BB183543E81EB7CAC1E5970CDC6F068C5EA118C7AAE +528D1396E6DC939112DA4460C890EAD5C01BDC438F5BB734218BA6270ADD0DC1778FD8AB16831D6A +302B814A1A44B07EDC65956C9E6CF4875DF521F3CE5B422F71081B6D69BD270F739095C9E81C0377 +934A8BC6390C420C4E4CDD9CF7E32544C68D884E15ACA3BCC07FC8C132D8FB9D752C15D75C52C288 +57E2EA461A6FCAD90C56843513F74461F18D7164BC597A28AE4BA7C86EE1703535A9B9ED50122627 +71FC12F102E800E0E1AF7BB46681BD2B14B614CEA91B7B2AAA35235DE76C0E113C92688F8EC81277 +D58C3406778E1EC1CC15F1CD9A137C8FFDAAB99ACE3BFC782916F1A877170589A92DC921E6740A22 +B84DC6BACDABCC76E64C79E3A588D80F8F4D376E1B426F15751CF7391102102F0AFAFD8B22DFDEB5 +48AEB5F30B1673023D22054A13391A0EC08DE6E7B685A0D031AABF20B7C62187C0284892D5EAADF1 +21BA28263EB863D5E36EA9C06A77CCFC0E17F593961591F84D82AF823EFE41044C8D606FEF83CCC7 +B0E961E7994DF8A3CC36B209D953E250ADAB8D22D7F2B4E2C9CA39EFA2D93E56195C1560E30A5190 +CC5B17FAEFCF250DF79F6B624A4B917E11C332222FCCFEC4F6A47BD9E75DA9854FC3F7AE554E91ED +DE144D7AEF38A0E3EDB5E5A5626374DB94F022C8CF549093041DE00D7269B7CE544E748439BA2870 +718C08E58FB4A77D93EBC04B7957D272AE1601D41BF85A2BADAA0DF73B0D3841D4839C85677FB2E1 +5F1D6CE592669FF4BBC9C69DBA334DC37706F2F6BE83D5863E8CD6A30C08640AAC4C233684E66B4F +E6B62D4A8BE9D531E47BEF5640D9B5C27D990092BE1597F6995C8A77BE9C18AAE6C1CF130775DDAC +41D34438FC7AD8E042CB56CBF2944932EBA7D053E9376FF398367450E35A1945FE23E05C921096A1 +5454721FFD0F429A3E06DC3ED36F1C170BE79C66996EF8337AFF85B90C5D3A4A94455AE9FA32E211 +7A63E59001F052D5F6223125BFAFA40901E98960ADF7BB886729DCA82FC3B8CC52B37FF2517299E1 +D769057F8154FB95582F02CB0BECC873A9C71796ADBD3E91324FAA94F2C41CF57C30B5897D031C02 +D256C909E080E70BFD1F32E69EF67031138C2DDCD1A8E4B65E485C23C3E450ABDD9815512D6F34A8 +4B9DB715DB2C7A93BFB424316E1AA44397749CB01088428F149A3B4324737ED9957FD388248462AC +1B2610D72BF5C073ECA567E7385CC959E37CAC7E05470160FFA5A9F63B8E9B082937E911586EA165 +374938F492EDF28CE6020953A5B5CCEC7737F9D9CC8538C4339567AAED3794ABA3B9F4EAE65466E8 +E326F6C399B36355935FBDCB9972F10B13494DC25097FCEC5A6398F275C8C151558E74C5175F7BAF +4155E36B733F75CF9D5C5979B0764F14D8306E06BA24BF791141E404C69F3F8FCCD91B9C58C2C671 +AAE7D4F9E5D6414E46ED633A5F78AA5BF04E652246A066EAD9E582B181CC196EA2D3CFAA383B5D0E +4CAC9336E119C08CC6AC55CBFBAE147C623B400453BBF447E96DE036FC025624384359EED7C7D5F7 +858DC0521377CF647A157FC3F188DE5EEF094DBA125510FDE34C570D7BE76AB5DF0A28BF45DDAADB +EA7EEEDB936332DFE93081E0AFD3FDD46BED08D6914B2EFCFDC41662A33B90B03D76D34F48D30FC6 +BBBB600E90E6AC7243FDF026762A44B4D6E4ECBEF48C9D7B696AF29EEE063E557D8FCF0F09E0136F +45D17E608DA36E59F2AECF8493F8D62536119B5F7E1554DFE3F6E8D7C9A2C6F557D18B4AF92C9F6E +050975C3B5C54F9B5F4E39D600B6FA2CD6DE203A174028CBB2A201AF126D1013C229BB82CFD013ED +199D01E51EE2780FE896E01C63C655087A3E61A7F1029FA5E97EA1872F1B45F22282DDC317E17926 +7368CB52DA9444F6055A3C653659CAD2A1D8712BC2B1B32C1DC6906D957FB88524EE066156ED6BDE +B8D832F9338F9912E29A250A8C4674E667C1C278B677AEC9972BE83CBA3FB779893FCB8F81A323AC +91474BA2A2334A07BB5628E905C518E634F6761A3289056F83D5DD7B3890987EEE1C18FB2D379CC1 +905F1AEB3B3D2AD578F0D6C845D2D40C4BCEE3F71C90E68E5417BB8CDDD878D83BA80AD8485F4067 +E5C3CABF28AB56CBB219C0AAB8FFC6C7E192BEC8CBCA1459AE4450AFCC81B9548F40CE2622E5A7C2 +81F74DCC02DAD57EFD92D072318DDF05BF42F1EA8163071E23949B0179CF7DE64677CA99B23CB926 +B3E294194EC13397EA1DC9A5E1CDCD828156CD71F81B64167D4FB01E6002713BD8AC6F82B20CD369 +9C6CA4704DC5C65A2D66EB155B7AF1C9BB46469416FB49C1C7E17A30A5F045271D7DF3FFF2F42C6B +470701C381E3456A500C6BB3D0E47B4D91C5F34B49BB6272F1F8698B307D89EDA3A1565DAD1C0864 +627560CF922DCF5B34C67860352390B282F95394AA2CDE0E97CE3ED39546A6AF1C52BFCF81A29BE8 +2C47C99E8050E4889E4575B75F39E662F2DB7420673797E2ED3D67CDA7AE2C15D0A0A794D57D168E +BE13214E89E0209AB2C0EB7784E9491AEFA3C02D0DF3AE5365A0FC4AE023CAB528162C7A1B173664 +9DFADDACA8DA5FA18B7D6489E4229E9E24D38A620464A744A5C60F6F9D334B908706B738AED18669 +8A8B278341FA4D65A0A88680BA484694921512F7DE93337FC1C02BBE6E64AF2DAD07603279D87329 +1D1F4D39C1DD6D89C90F65240F4808F6F1115CA55B88E242565E59F3BBF1F10EC7B88872E9AE61D4 +4CAE185463EDFAF7DF63DE4D2207D307AFB61501892965170D2945846FCF5973A1D458607F50C15E +06E5BEC715E0C156259AAA6C735593E5564F65F443B78CC7512EC35A56F126DF9D30974A40872E42 +65E1AE5FD483CFCBBBA26DEE426CDC4721F19C3FDA86ED7AD4FA1120F63669BEFE7002B128CEAFD8 +C63E8AC09943B6CBDFB3D2476A026C00A8FF81B1F651B97F310C82ABA5F388CC1DB5AFCFF5996D52 +52A6A42FA4D972E41EE56088F78CB966F9051171C472C774879AECFFF08BFD9CEA40D7C298922ACE +64F28C14E0B81F4DCADE81D71DE3983D87D905192EF13CEE71B2D3FF1A88AEC671EC318917DF98A3 +C9054E372D22A3CEC82FCC217F47319A40900312F6E32B536B9E7A7FA0837EC65CCDB5FB0D414371 +17596CB39D9382262DE6E65379D3A9709B2CFBABF5FC5D5B352425F06F88CD31012A2A4147B112F0 +C1C0ACCC808CD625E0228EEF66661F70AF96D3DCFECD402700E4F6522AC9A856DA466D55C84F65BE +2810A1565163872D62EB81333A698ED7B68352CACCA2D7AD38AB55C19E4F5582F75818302F5FDADF +1DCED09D94872F2D48FB636C8E38C7563C72C771A08C6B1F041F3532BDB39006C89A33C09BE1E3E6 +03622D891F98010BF1DE5355F557A1E09448D486ADEF565705277B31B8BF2B86761E32631E3435B6 +88B79D566F1747BA456DDB43CD239FB47FF7B425EAA4C657C8EEC26EE01AED07CF916E77D53634C1 +37AEEA009C6B515B6342C54BE2C7B95955B1A9DA277A0ABCDA2346E88018C726F481F71D6011AA42 +F8852F2E5749518FE3B3AB668213FE1A05C10A1C53953D75312631D6BBBA01D418199DFEFF8CF548 +6109B099FE8E2F606165FE30F532C03567785D5362AA873C9D3EECEB20F1945D55F49B0CCAC84967 +59FCC7292E46938943C262D78F3212D3F9D0F7B103157F423D71B1ED54B2A603F4C269029918F238 +EC6828FFCEC66009DB9C9E59534EABB183F31D7AD4C57B1BDF0BD2CE5A421882BC10CC1BCE6A970E +2B586BB221567CCA483989DD0B8DEC424C1D1FF042DCB7834423CF244EDA28D2D969B17440CAEAF0 +24A6119DB010CE366821AFA424D1B8299609C04148275AE6E5257A7ACB3C766C747CE99CBA2D703C +F19B7CF301B634D8B613DDC4AFE4633A4D77BFF8E00CFB5E289EBBCAC90A24307E7941EC1685CBAE +400CADD876FCEF7F6557EEE167D2035A05120293527700DC510B038A496BE1D5CBAEF24ED39F7421 +1A93AADF22214ED606A80582485AFE358E3A46D0671148998A3B3BE209467009B43400870359D418 +9A8CEB4D5866AB52D16D9CEB1EAB71C07E6CAA34B70E3096BF7604C22C40D5FBFEEA616DA3BABD59 +DCDB97D883FC8742B8267A16A99B7953225F7144568D566E64542C92E538AC140C851E5D295528EB +7CBB49909B1CAF6409C9BCCEB325468FA0B5F7CB2987382616B477CCFE4F4AC79E4A6F7165363543 +F04DE5B6F6E1C2E910CDC3CDD6C4C92737198F892337DCB6647BD226C820AC99C65D8E7772BBB74F +E65DCAA8A22C33BC168BF48E40A82700A3A7668C5A9A71E397ACDFEE7D556C5C19467B7AA69C260B +727407AC837BDB7D67DEC055C1F45D8BAC61048C45BC9FB3CEFE7549EAA2992D2EDC126FF7A05EAE +58613332A2BC1465B2BC0429162B907D65F793D236EDDD8D35405866D71B25F62DC4A7E06D4DEE82 +840ACCAABC0774F8A63E9C0F7FC980B3583E7A8B01C46590E3BC04EBA565C2EA94F057D964A78A90 +EA9F52ABFD70F84E44E434BD10A42E98C794065724341F907E35D3CB257161E01C7084E3A0166D15 +CED65DA7BA87DBB2EA33D39BD99AFB93D3548358D08330E807F8552CECF63C84F805205491BA3A1A +622E70C232FADF3BF2DCFD6F0539158D3306506F150B0518371912A25EB96163D73E9EEED42EDC84 +D688BC7F7708D9DCA348FAB4DF62E5809BD094842D0A31DBB7C4B41F94D946810C5EC10B69AABC2C +91A59500B2E5D37F4755DDFB7AE4ABF757F4C5BCF77C7F95E6A616646456FE8F18407080BCABBFA5 +7704287AD26222DF91AB2613951E2D679472F8ADF06EA2A20205EC19972299A78BAC52114334470C +5F5890C2F846B4C6042D73945127F2E3910ECA1C4CD7A16EFE4B4BE38A15AAA710682C3836A8CA83 +FD384970139D8B46FB0AEBB002DD224199672FFA02250FBCFA4E649E335428FC71F50F45E498419E +DB0E970F46894A48F65580881C9C4250FCEF65C9B28699408E18B26FE6DB7F1CBDB767564E73CB59 +54C6D639CE33220C894F36E70F71C9F9AA3FE2AE0AA0E3F2E304EC5ABC661675CDE2E70519E4220A +E26FBACBD01D5169EB844750753E6CED53E3678FDCD08AB93E10067E9C64F38B40B76D99B6CD92BD +F4155A1EA5CC824998B59AAD06E09E5F15EBB2288D66EA71B296616734FEF2796F07FF0D8B047074 +A1111D68B99C2B70FC56E74A51B062F4998ACC85B1943C9477E436E5CD7AB18DBC898D21BB93475A +623BDDA71D7B895BA2D4C10F4B90BF335126F4FD57D73AFA50170F6B3C364922E551D40E35DA75FA +891762FA23401D39260F2E92C7807C746F13BB35CEF9DBF2E76E66A72FEFF095DA482A4DE8A42091 +7065736CF4DE904FB52E649A32255E2030A7B31B686353492F31C064A3C4B0448C4BFD44B8E15384 +FD809B8761EE26A7DFA1758D57CE4F0BC376EB2B3833534B15A83436BA553955ACB5A7A66796AC5B +92DB5388BC53EFA27508B08E82821E5CF669BCE52BB860780F749B4F38ACDF5FF12726BF3EC2743F +01014CDE96FE6B4C40A034E9EAFCA2A35CCC776C2669E6AD138070A40F48ED79136D7FF57E993E09 +B81C543FBADD350FF5B5F7A46F060F88E30FE2D8233832D18B6C323EE017EBC1DF5C838321CDC8A8 +4CABCAB20B60A1A3AA028F36EA6E87C850AF8AF7CD50AA6359038BFA8818821D02CEE8F51DAB8C05 +F7AE9797814D97F3DB8CCDDE45B21DBB15CEE292FAA534A5F317B357F4091F3DA357325B8B9F5EDB +45865415973C143E5E5BAA483FBF2D06CDD4246675EC58B84C6AE65CA743117FF00F229243772561 +31A7F2BA26A9115AFD96C18216CFDF41B7220ED0CB3FCC26C36380007B382A02AEAE428887DC8BE5 +FDD630AC57EE3DC156C7B8B29E687F24442E35CE10BA4087295A641F7139C831F7CCDA6CCEB5DAFE +537CC1A97C5A337D3C48A6AE947F58A30DC08CC7B58DBBB4737AD52783C573FC1E9408F55495A80E +7FDA61F0B9C4F090158F1A416249EBBA936C27BEFDEF19D1BFB839EB70576A010706D8B95657B218 +9C2AE04C11EF9E57FE09880273761FB4302C388BD608FA0C7F00F033C9C00F4E3D5CE2D903E0DA52 +E69C7745EE9FA75E2AD93DC6CB5CCFCD3782A699B807AFC36AD1F62B05856D5DFD6F88831B90EB3D +CD523582A49732E3FD7253126D39E8AFB8458B5F7AD7F94A8DAC13365F433C857AF4A42C0A08C4DB +9887C4957259ED22D13CFDF5995DA957EA5A0F620B0214FBFE08AB6D552DBF048D62CEF6EFF12F15 +3511ECA7833E0E3E95F85E6AC0F95438AC4C126E1F1ECF336ED31CCA7EB216D279877123FD9FCD8F +B5E52B587CFFC4428456DDCA816819A8A4A211D8F1629E5D42BA4C5C356E580C8A22C61D987552FA +A97893816DA73D423686E4EBD44375C257F031318865A20F22115E72BF1EB9F93AAA169C140A33A0 +6C35BD4526A38BE79CF40AD1EFA10411E8F3300A8A8B97AB140EE6734E1BEE6C8EE443D698D34159 +97649C6F10F20ACD80236422E215E146D744A262DA3FC88DC0D86FF66512F49D3F957D3C5CFFEB42 +4823509F33F155057A4C6F37B52F4667767BA94F6B8B62856B553F307E5D230C44CBFDC9A97A45B1 +39FFB2F2565EB0E22026972FAD0FB7B9576FB6F368B61979943A398773600E7EE1DFEFBF26D45D40 +BDA66EBB96A56EE9CAE0B2420C5DD83E24DBA9FF885BB844BF3D2BF93B07325DFF60C0CB5FDCCA0A +C8FB5A2E119D5AF26E53AB8E3B428481C2871DDA26EF0B621CD8572B3C664BC7AAC01A1D05B98F79 +1A7080D294BE81099BDA7982432F3DFF4775C44D23F4F1B2E0162B61A8B2CB5EE8564BF98E2ED403 +2219085FE6194C19DAC98A421826CAED7F1AB1477AB327506010217283894235D7DBFC1153D5ECC4 +8AA7293F19592B4D7E95FE55151889BCD1D7FA7DC2370D2DFE11D7E4EA34B5C7A8E73BD3A348FD38 +9EF45B6167FB90BA44C23E912F9A4F2FC0427ED070592F7110183BFDB2C400393BA7569058227926 +351F07FED4F33633BA03A72AA2DC6B598E49B96021DD868DAD0F352E5722FB714F667C15C68D49C0 +3D822D82677EDFE86FE9668E537DA284068C9B0AED83074C92A5B939296D505B837E6A9DDAB1AEAB +7455A08A114C2222B339284674B74BF4CA9EE0C020BF2A148B439C71C6BE51A94CB64FBE4A7EB295 +5A455047CF5CB348B062ED4F6471CBC3E9ADD9BE9B96879AC7BC71BCE02FD02F17C6063985A5E898 +3D205AA1489DA13C408990ABA1C54F2F501AA172F530480D789C848118C0A74EF98D5F607A067BAF +F6030D887AC6A6497F9A0B38F9705F328AAD4BFBB634F739386177B07F22D5771282444E5EE17335 +B4D0EC86117C697E79A5F4F65FDC08E4904DAEDAB20067EAE2448FD4301849E456D085F392DD1316 +7ADF75CCFDB723E2904A9C0C976D6B84DDEF9D92B0E15FB246C3ECC2D0BF314CFB957757B3A3E8E5 +801F520644E4601D291DA0F7507C06F3B9BB36FC1C70EAA444E14E56C0CFF06C7F853DF36DA9D8B6 +AF2544B853DFFF535A7E5C6FC145250CDDA229956019659D0D253A19A7B51A4E538BDC01F74D7704 +9949C2C97C7EC6392C2E61CCC0992B66DAF1AB08551063E53180D2A67DE496716CCBAA45462D9F91 +B66A22545962DDAB120511FF08627131B95E5DEEB8B4DD9643E7B2AF65C0FDCE11F5F1E8DD468DA1 +8D41C8C4F00EA73836F4F70EC50FC3EC6D358C0658A4261C6D15A582A2C7C994E7882E661855B352 +014576858A265FFBC425160669CE159D07EDAC04D060B44E5800A7AAE8E339C29B929AA81D2F515C +46229D2080D5917AB20AB6B34FDCA8E4AF64ED660A3173786FB1A1D005D575C2A5187D3F7CFDC94C +CC44A38C5CD523E9DA726D8EFA6DA7B6131DFF3435FEE838B2C7D6B97934295F06202D307FF78D90 +6699CB9C5BBB10D1D4DEA5FDA5BFB094E704607083B646D37F5DA1FC7AD21B813F44D8C1AFEAB666 +55AAA19703BEA2E77DF3BF350E17C74B3447A452235919452B5175570A006C7680AC05E8950A62E1 +1D7E3ACA35A397D1E19630D094A86807593C97F4C484E4E06BCFF708B6DCA972E3A0009E1CAC0EA4 +141530F5C1B8AEF5E1B933F37FDDBC4BE22B74FE346D1A3F5FEC0818F8E61765568A2AC04713E828 +F98C449D9A1CCE52D10D61DD8BFD084C8D099A75D89DEA64D5A7CC68BD5B0593D97953DADA976383 +F5015915618AEC56D71D1DCD55B89736395C609B315A3F1E1255432FDBD37F38CC43C354FB4B7C44 +F1A7318B0B7E99C3C08C33B953727B6A6328051783A0A33E3CD9E498346A3CA6A77B517096EDD52A +E443B87643A646C3A7BB97F742888D33F9B3127E61942F4103C1DBDCD8EAC8F9E259773066736CA6 +53CE57E8822651261D847C131321BB9D6626A1AC50D047C0BA47B411DF2A995545BD68EC0287CC9B +31D5DDCA8755EBEB10ACCB3903AB0FD5788E984220443B8459E7C078DA4289F1350905881AD6DFDE +C47302B0ACB0D4AF8CAED02B4B70DF3CF8FEC118F0FC2D3DDE3E494CD160E676E300BC464BD4400D +B50EE43B314E0517037BF971ACD7CD327CB2134893B8A0410E68DDC518F5DEC966C7884CF5FDFE74 +723177F20DEDC039D879056CAAB4BF045062D3904F615C5CFE109AC7A35599C94024B41019B9AFD4 +04A80ACAA4837929F5C9317680A13D157A03B59A5588DF79D2E113F5F51021D6F6F90E8BBBA2C252 +FD10651BE80BAFD59C53A3367BA3C28DB6EB9DABF1EA99F47B503F627E15DCF3FD645FC52C5D5D0F +2F07DB4C25C0D1E1C00146E1C4D973E613CCDBD3F9450CC0F5343D79F05E9492E86A1BB889ADF405 +03BD7F3E7543436859184A5B20BD8A172F350D846B7570803990ADAA48D4B9155A2B4C4BFBEF1E1A +065C08E03928559735BDD442FF1E83E1FA20A5DA57D8BDB2FF5427C034CF0128AF111E6E73099E04 +6E0C240E80A73D7BE72B87834E45898D475521CA3306707631F5C6136199F354632D1A085F12A1C7 +C473868B62E534D15F5484323E63D0574196A19EF175214EB35A90873EFCFB92D6CF68761D45E37E +AA61E1A1979A82009507CA193E44B36A806486665CEDBCF387053ACEAB979BD35D30978FC7659ABB +E844F4ECAB3303318ECE80777A5FA5A9DD91B3D06804C4B4E9B4EFCF07EB89866D0DD8CA390CFD15 +98651417114D78776B1A1D36B4BA17746D6BE7FC123D473EF1EFED1C3BC1D555F914536869FD5B0C +35F9C83F65B0E6BF7A627B9202D787D72C600DDB6BCCE613D88492E13CA0AAAB196E8A49928C62CE +A4FFE2D0208EDA334ACF47F20BD793124D2C5546C03F4A364369A76A0425262F9D9118AF54E37D32 +E33AB25DD533A49DF5FBF1BAF4CEAC2D9D378CDCD13B00FDA432D9042F623DA41AFB80699B5538A2 +5403B0B3EABEC9E8EFCF42FEF3EA9F91766902CD206B0787C187D5370B60AD6DCD002DE2DE8DCDC0 +B4719A797C5E26BAA67665016DA0D967FA1346F9588AEDA174CA001B31213617FE19EA218EC23597 +79D979E2663166489C06993230B0D07973A117C4E3F4A4C93CF8428248DD5389414D679C69644142 +67C7FEA17E35B0CEE456667A9B1875C81B2302BDDEA2818D6019FC1622A82051F60584ABC904CD91 +8676305DC03FFBCC64FDDAC8D8AA9CE2EA00D6C97BC63C8A617DEDFC0E40775649438E9F61AFD179 +5E3B20560B01BE5E0983F136CF48AB206954E41DEE0D9DDD953DFD01CAEB569151D6BC0DFEF29D70 +FAE3E198E7EDD8922C0E0BCB8BCCF1C016142C1A8B337AFA7A05A9D7534B184BF3BF827F371E9BD1 +9A71244ECA1BA73D484CD2FAD54DB2F0EEFBD54B536EBCB5094E6BC2F5B2AAE41F05B4B311115876 +ED42C34F8E643B53372E3F6350DB8A38445822EA9A33E27FB0CC42CEDCD1FE2FDF723FC47C996EE3 +56C402112F24D0AF899B2D00BEA1CFD427998BD22B2A09046D6737814448ACFB10D387547D7009FB +384AF0562C85694C071584236D0F1F3D3FCD0CFB38B77C81889061E668BA7AB37AA60F58A3967DE2 +6F939B79CBF10A9DCC42852561D8D6754F1B660D216AAB1E133FBAA321C56E2584BE5C9BAE20CCF0 +0E8DBE6D9C2FCEBEBAD945C3C04101D2387351F132628786F6D9D4CAB83419288D31F9BC600D9664 +12E6AA457CE6CAD26A4C0671097B98C2384C81DD8B9A3222D4F4BBDA7017895C3EDC26662779AEE7 +40D9D7E24185FB821970B0A3A94041A69E4805EC88EE1EE521981536F2844FB8F5EF645F67D42CE5 +148E2DDE43AD5AEF200EDB3A2C7866C98458A92666E5F9E070178BCC39F65A893102A10564AF4E8C +AAA5075D2F8CD7FAB0401C03AF299EA3515CC93066744EB5AF7CF0ED06675BF049A6E3C211A89E16 +DE5BF0445A7CCA6EE8EB0347454950485D884606651E5887FE8B24323E2AA16DE22FC1FC8C4F06A8 +2A1FDE5758976024068197E1F4506E4D3D8A16D40461A4586338B374A592DC60334402F76388AD6A +457DC3F54E6169CF7AE3959676E966A45609621055EC3AF80E182633300A4418E34A66DDFA6B569E +5A13C9115B5FD3EC1CEBE50FBA247F60803AA83976F00117536342DC3D9890C49B2AC701D370E43A +955118967827760F7091469C5406F08F18D7E3548148CF0E312B1DC71DF67A5E7A1656CF2F47F3AF +F3DD50FFC2FCDAB7177285B29C17CA43019F62AC6FBA52D1493ED7C427526470ACC8389BAE827759 +4958908F517B2863B83292EB5AB3F57FFFB08393CA610FB1FE905D88A0A16AC395E2A2A6DD033D6A +0D68992F830B2E1B95FE357BF672716E88FFB92FFC3D62945D1EAD22BC68C51EE0E10A43011DB94C +44685A5C4576F6EF44CBFB45F2A4BF110A01657DB51FD499767E78058199B31DFD60813F1A344F86 +289F9378231D5B151C92385E3650B4FEB1DC91018EAB8474CBF69FDC1496A4D078D2C351C8196451 +247A9DCF8117E5B637371D8E22E248C64D999015C3FD2311E9950B8EE0922FBDD3D7BFF766BFE9E7 +CE0BE12F318FF2A7B5A9C6D00A54401609304ED2C55F5C1EAC3D4B38355BBD85D66D61636FA6E30C +2E82829376BEC979A6FEEE040E452359768ECF90CC539A546F17AE906C76F14F86FF697797322B05 +1EB311A759FE260C1EEE5DACF383816AAF1294CFFA7BF87A4D9BC595EE8F2C2F86FEEE11AD959D86 +F22FDAF4CEC098942A57E57813A0FA99239E994FFF353C1E781D666B8928CFC648FCF0869FC68468 +BDBDA7D280DFAB8B0B3A4CA35B074B686DE8D372C61FB32305169A1A9912F6541DA16CD6316A6EA4 +51524757BE5CF6E820011BE3859FB8B8578C100FF029680E05F0E0BF11D33FE19460C85EA5E4C0EF +28E29407C8AE6BE01CFA0D5022BF9FB01416FFF722A784DFC8FCE330EC95737A854471D334FDC58F +AB42867A7B62836A8B56466E9A6C1247D46EBAFFB905CD4321970F59FB8D6FF65FDDD34BF913AD32 +2E68455C5FF2D23C1A5EAE687F259BC982B6A384D35440F7C693CF50B9ECAC0B5578CAEE87588B56 +2EB6B7F42034C9F2E545EC866316552354EB3728C7D26527ED75174EAF635E048B08DC5D23E88981 +070AD5641A652F2344956E9CF4C16E652A99F4A644D1787D6D36537489DA4D74E61B2FC4DFDF1D1D +9D58F9C26C5EB63200526AFD168AC57D5611ADE4D4A382FC28BB60F9E7D626A6C67AFBCCD1183C5E +3CF2EF210D0BF5CFA7BB10FA3887BDD4CD96EEEAA8F9219AA2F10ABC0A960C3B57C0EC0313AE10CC +FF1F522124CFC8D2D49BFBB0C193EAFFC5B48FB3FF30B21CB76F0A4C0F1377C9223145BB0468A5D7 +1B9BC25873EA12E1C60334571C67385C00D0B570D3FFC6C7FF0DE62C183C76AEEB12DFFEE1459E0F +C818C621B8D12FA1357E2B55D48935D70BF140B4CFFE8813DEFD479350B20DC2EB1D3CBB1A2D3DC6 +EE975D58C89D61FC50E6A0197DA9A586B72255023DE47DABEFB11E8AA02414C2FF6258A281219B9D +DDFE41BA7D7977D0D6F18224FE22F7D4E9355FDB35BF7ED3418F4F68D093AC48F7D8FE4194FEB6C8 +0B9DC1F74E023C604DEA27089F98C3973FF9F4AD7BF7BAE601DB89B08D5D8139B95EDCF6C885FFA8 +B3E4B0477E7040225733826BACFD1EC4A0DD72DC41734856AB9FB700DF83CA2CE812913BD142D84C +5C83C0B2583768198AF9E885F2BA74877A414233207234AA5F18840557CA11682AABDE8993533887 +7C6D404BDE4153C9827EB16D66C1D73A8143C8A2D3604FF72CE579FAA3C5224BAC48EA83BA848429 +9472007DE96466B5B29ACC7C03B05DCAA38A48BFF9F214DE43146AE4E04FA705421917F99BC54533 +F0EBC01849E396216B9F0794E6F6C6B61B52EF1B1950C0FB609895C3C55FF574163FC8B6B09E66AB +AED1810E698FF37CC1F926B2CDA3B48C7D77790EBD2D514B6F385D397F713EC3AD3954EA9C846158 +6031D369E8B99E53408A79D64C34EB5A56DE8A67DE91837960E98A66FC04DFA0EBDE21DB003234BB +78665B039D0A469A0221BD541AF7149A2A659C300132C14581EF766FFFBECBA8B58A5EB3F95446DE +F49AF863A8113D17B2E7E6ECDEAFC3834D4DF900E3475596E86FBB4E2974C090DB4AD61A737D611D +92B4535AC291C56AD8B1C031D2F9B505BB77517B737D70AB3723DB52AE2ACCD5DD2F617423ED3CC3 +9CA882EF41757BF7151806A9B8B0F312808863E3673FB54DE939B35CDECA7FBC4DC3BDF5A5F47D35 +E345916C39366C8B4F439CE1C6F1835C320BD1E67375B03B5DE18C93256F251761A4C8CEC01019C0 +68E34447BCC503B9571FE8000627A6B3DAD5854CBC0A2D69E5A8F46BC78F6A7B1422334EC7A98ABE +FE9B83E01DCF3C6C9273B346F3240EA225AE4A4083CC7B0EA141A0773FDE940768358EB4B13D82AA +304A1386D450C1C0C6A7D5A8FD2BD313F78F85248B5196241E31E5595F3BC01F37700A2DD3D4A0EE +2DD01A36569CD507130E8F5B1E96CB560BB7DA15560CCADF3B2C9804A11D9E8055C9EC70E48C1D21 +3EB756A1376F2EDCB7189D78CD3D6CA5865537EEC31C17D801605EFD860B0B629472690588D02575 +02C6F7A75B9A1C1B397781329832CF3EC43C09F1559CD562C48FA9500295CD3B0A790DD3FCD4684A +7C7AC49AC9BFFF36B39A9FB148BC28D37907433943CBBF0CBDAB46D3EA86DC8F81C859C52D15302B +94A9B51C199B7104DEEC9D769C2634CECF8B700CE9C04152CC59C9326BDACBEC4312DEED92DD087A +1C4840868D9F97CAC046581F762F75E8D24D6445370A3F1E0AE74A6478D9DAC37E7FA5BEBEC0A1E0 +81AF89C1BBF7F51E3E2E22C8C405E8671BA85F1BF0DF79A465DAC7EC07F731E00632E017D190A99D +83E27E5C2E63D7DABBA23B2E88334C63721AC5A4CBC5D45F4C177259F34C2EADE01FA008AF65EBC6 +01D8DD16436D86AA94C99F3CC0A2F87134E73BF22F108B825A8963B49C6C685474AFE4A542C8641D +C0375D7EFE9AC1168D9700459BE52D0DA399023E141969F25C0DAC4668534B6647EC85454BE945E8 +26B26DE6E3C4584B97A38E2B40A0D23481BCA78084FE80E00A71A790BF31DF468A435ECC88E60A57 +860BBCA3D65930186E9917CBD209C230E8F8255A7ABC7D3F043AE4D7AD63D9980BEDF062B7D5C298 +C40225B6D03F29A0339E0FCA02138E526F06B9EF47F5E7A8068A846CFDE2BFDEBD24F5A73A66C079 +18662AEC80B43246284FA4E2EE0D9AAB172B1E59A6CC46B801149D8C0DF6DEC9A55D8E1B0EFD9D30 +2FF618075944CCCB6831D336B11617107B0530D09885E5CA11A5F1FCC8D69D603DA16BEA51116D42 +CAB1AA1E4D7B9B4D79993F2BFE53EAC904FEB70B2D330A89780EAC10D12CC0C35B8399F218AC2976 +E57A26BAD20CE2FA2AE2363D3FD2A8A971747556F2959DA74A8963C20B504711AE1CB0D0C02457FF +2E9BF696B159AF031DD5155F21C0F5549B0471A3C5DC8918B675CEBCB23E29322B959ABC05283A70 +2E878DE8EF25EA760F3C5C7B7B49D398283DE2ED837FD59F7C22D62C58FE4448B1049FDEBFC8787E +67D7DAFE9774979BB3802254DA59BCC0219F98C219F84D995CA768B8B5D9D4A32525DFECE003675E +E4BD5D8DFFC11025AF2B468F9207B5B2B42349B98232BAC0759758C1F4A283405815BD7145C93FA0 +8F3ED2826655053A3C2559073D8ACD199DEA2C5BA5F616A2E48548B4370EC73493BA07E197165DCA +774438B0766867819C1154D1959FE6E01E6312E0AB91FC2E2BD240FC8652A2D456A1DE7F34EF372A +53794D4C4E050BF3CA5B7BD2F1B8DE93B4C8002485CB219AD2D029739FD3C81CC6E78EDF38723576 +1A57143EEDE5CC887F282FECD261F6A25D0A7E154ECDF5DC38E426811BE86AAA458577E5E0C5F0F7 +5AAFA9C41E5D1DC9D91ECD79B514F8CDF7A5F1A189470D35FDF4F9B8788879CCBD91B427822ED658 +389E981E0EE5F7FB87692A3E3E931DF8A1D1573E3B0166204240B7080089A09EF7487C9AEE2D665F +5A82F94C877FB5B0DC531CEBF1E71C6592CEA2401E4B5122E5091DF03D203DF979B9A6EFBA12E2F6 +B422FDF15D49AC0914D372D21E871DE65CBECD105FD4A3E4714B9CCA5C6803FA39DBB015EA8A88BE +7913502E562E5B170B87BFC8572DC9DF49AD63694311EF1334444BDF0B4CA3245271C1F7A4D7FAF1 +703E3AA0E1EA8D5C6E821B28707EE0C9B4F22F23796FE87356C58AE2CADC191F4C58E1FB58DA03B4 +5A25AC95DBAE13A293474217BDB214742B9D9D6AF35F70FED2891942EACE3E625E55FFB820543FBB +250A062D3D395BC0F219ECFE0D76686AC148BC41476A887BC494DDBD396BE200FD3E03CFA12EC9AF +6B934A283C42AA05589AA6B4A8D16946BB51F50419CABECEAEC5AEF9085C9989289E9B46BAFB6FB2 +782D84DE2B068F91A9744AAB237CEB1BA513E57E4C307108E993C972A3E0A898D5A8D27833155031 +FDB98863C3BE7FEF3004CBAA5CB60A1F2E3EB4D7290FF5FAFA088B1CECCB6CF51A58DAAD998F0839 +6CDFD68F5ABC9C1CCB8F6514107773C69C26873E889D1F79D10E866910E4684186FCD71C965ADF62 +39BA3418B313A27AD632300969B6F284519366ED85E7CD968D64823F8C59B5911A72D0A20EB72B60 +3A61E36F52F256FFCDF706B4560B4DFA5D918FBC530D83A4B3C01BDD3CB4572E24242D141BF9E775 +36693A0407D002E09CDA5B195BF1CCF430AE9824C07928A050D0B460F2704BE8F9E647A4884C4567 +0A81EACF7CC038643EB0FF18A376FF6F32B6FE4F197273327FBBDEC6443A299CAD4B26F7778A99F6 +5A11BDE047153E764039EDB251936AA43DEE50DDFDF8856519056AAFC4C5AE6F2051AF0579A9ACD4 +1D00775D7DBE70022CC263DCA5E0A25B9C7C4F5C418587666B2FE24816B1E0EC92F9074F1403BB83 +AFC3F1D52CA79C387BDEF864366E34C90BE52F7AA09935373A07E4E026224E76F9EC3CB9E7EDE50D +EFDA48248D61F3CEC880A3B8843306375D9711E58645F3625BDB8E87052DA67F9794EF4AF8DB0BCF +E00677C3A26907DC651BC838C40EC39E2B5A5DC0DBD345944A6C32226089D63C52490FA10B215AE7 +03CFB663EB8A47793B84CE7364DA1C4E7FCE32DFEF09490121222774915BA59C78C2275F829D15CF +4D8686B095C38C731B83D48738C25F40B8ADD487C350A2EBE846C3916AE384CB1050F9F5DFE09FCB +D9129C6270FD86D55A459618FDFA4F907E6B4746196BB717865AB378414029017551161A52E9D24B +E4F7EED553A927933D4ABC8F25DF607779A717909CB4D810DE8F5762581900E224E4B91598149BA4 +71CF8068ABE8744356B261600BFCC57FB8BE45036CF6571D9B2A95304933BD4F17215F8EF53F8E08 +1AF61FA7F9583C34EB5655CB0ECB82246959F09091F36989EBDD646BEDCA614B9A61AB7696B3FF18 +1058A150FA6EC1BE2EBC7F64357A3FF2A2B0491D2F4E0B970DE5B7788B467CA678039B5EF55C88A3 +84578D427FD2CB16C87B0BF0A3D37CE8ED43E0F049AF2436344D5F47C948C632C94A287509282561 +6C64C5D262FE5B24916FFEE982A69A6CCF888BD01D62EA591EEC51F4B7DDFAFFBEEA93FE08D736C2 +0129E345D06B10246A5F57151C198D407730713F32299638EFBDC01367E23EB59AAD42A83AB41B43 +2DB462652E29813740F4680A5D4BD47B18328FAE6BDF4200CFA4CE3773809B45E8887C9B2E423698 +9F6C48D64F5986F563D9A7538A8716082F81936AEBD0461E6F4BD470436D8B7656F0FDF89108E6DD +02ABDEF907731D458D690BC608EA9CED09EB1E6E64C0790C7A2378201CE997FFE0317679EE1D4EE9 +F91157449323E53B4ADA8096CD628B5861BF794543A98F2FA2AB54FF0F25A13DAD43DAF9394329B9 +5AA53CA32749FECB0B2BC035DD1EBD53FF9FB5AD8BCE06CD89E5568091C1CC314CFB1D9821D7F9AC +7C55F55E0A16E39A87D43148201B928F3C42B110FC056189DEF183745F3B637441DE8BD4C3C7EF12 +F4258E306B2877ADAEC63441010750DB4E6269A4C78A0AC01BB3603C386651FE814031CB5D8C1F14 +9EEAFF652A53E57BBD4C8C0CE36A84A319A53BC1E5FD3F1ED1EE72F4C1A9BF264B594062FCAFB22C +C1FDE3F2E3D3C17DD3F7FE0E15EBD812D550227C06D01127385374A11438ABD50048E17255FCD2BB +85122A6FB9B7DA9D5E9DE8A747FAE0DA45A1FCEFE92B9E70A5B2CAC668D4D07527A5C1403267D823 +048BE671F725CFC7474B44FC5AAA348420B2D7C23C6CA066666FD6F2208E329878D90CEF1C2E77ED +22D3BEBB9D547810B189F08920A27E7107F208591A84D463CE2576C70C3DFE6643E4EA93F4E1DAEB +41D46F0E2F56FC10C69AD5034FC9859D31CF27A3A1EE256C93111F81C11ACF1FC0CE20B90BAC9AA3 +27A5C85A7985B951519FD4B03C40BE637162AF41B2FDA68F0D1E9B7602FE2659D3D75955C579AC51 +DF6A552EB9581AC3F712F083F19B52A6C4F560F36C59CEEB0C996AAF1728A2AA45DCAD79BD7B23AB +388D5B0B64A2B95154B6259B730B0F4A72C8C7F7CC93C7D64D9D8810D1F63FF8ABD4DB89824E2D26 +4FDEE916C41E299211DB1A53256E1DB5CDD04862F034D9404B73183A99D3D13D642A663F129B6D16 +7095BEB4EAEFD03DF2FF2F0B6B594C1EE90FDB203DA89FACEE23F1BA3901FECC75FE1811BD701259 +343011262B6A0A9707AAA6316BC3C17F787BB80AC8DA5AAC942D90F80C5A3BB59E47EC767244AA95 +C63E50BF809998957936D3BF6ABC24B0A397258F9EB4DC8F65692CB023D9091FB180C69498CD0C08 +BBEBADC84A7E0016E8F8BEA325D924EB0DF82E75D2CC2CCBF039B11934363D4332C5FBC5EC556BE8 +5EE4E707CC2753CCC43D2ED50558E51A104221C9323CDCB0199B7B83454DE3FDC810D0F362C0299F +5DD981B31D8E3DDA284FEF9DC8F9C8DE138D3065437A7FE8C30572AD06D62E8527AD37AE39AAB0B2 +25F76A25F6C6505241ED73BA494CF923E919F688DDEBF193E188F8C4C154F21631080763B4D091E8 +AD1D2FD6649E0CD9360E8D1A67A5B5FAFC67547CA31C95A5EA8D4EB5D68B9F6D6532DB9B54584735 +9558542A2AE58C09F3BD2918EFBE1699E9C8F2C2A11EA4D224C726D2ACD4A8D8ABAEDC6588CF2AE5 +66528B94F55B823A2A1F7BE19000F3E7579D094E047075DF18C8C868760295533B26EB3ED90635B1 +29C17ACA679C3E88B06998CE5A7A2544B700229F5A6A504BD3E45B276471959C8A3F81917A534287 +39B5EF9E3D463B3BA7318448E2A3E79520D2D245A2A72F31FF7070B6E4624E3A5E216BD103640C8D +F387E49D732529C611F8B971073F17EBD2F6EB18F9B74A67E1997926DF178D4C9EDED435B9682F1A +279C81BB9F60DAFE125845A2FF3B02979E5481C78A45C479BEFB9FEF3CE2BA9BC46C77B50B03E48D +A6D17B76F06F3AD118371ADC69E178C52B5FB4B261C9311874ED07DD6D5B3226A005FDD7A6D53848 +09E7063F036CDEA41619122635E835D2D74CBB6AA9B38CAA4D819C26E95115FE0DBAB4198FC5838F +2C91B7A87B07D734C6D4F4F83444C1E90AA9BFC908A2BAC4B3DEF9157AFCA5248F2DA31CA87BD363 +AC25E9E77F741D4B2C6E02F04987A6F49D30E9038CEFC41BA172DD675AED8B392164411144E5B738 +F3210B0E66B17A13CB9631C33D44484E792A7C082DD0A5382F34C5637653261B1EB6D2035B08B4D9 +1FA9AB770CAF40A103629511F7B43F2743D7E583433DECFB19C21FD4FD0AFCC22A4119E77C87BFE6 +FE50068B22479015BE5A9F06BEAB4D37412E062A45E0CBCD7BB39FEE747E96306F79FC4F2E8942DF +5D9DA0E55AACCDA547DA19D30B8404FA121298B44C9CCE198C708C69A8D6BF17591C5C50D3FC5BE6 +961F7ABA8F366DAE957A1C3730DA4A5B4F035A9274675EE3BBF0CA8CE9D8349F50CABB1C3EA4948A +BE6F9F143592F1EA95404E6909A909168E3279A957AE1924245C356331A75E7008BEE92BEAA304BA +40B7C3F48F74D9018B3247DF50EBD7CE541DA48ECCB1B0BE51A455C3C13C279D4D8676078C3EBE43 +08748D52C9B041D3E7244C745B1F2F742D010A9E60695F3EC4FDC1050AC082B905D6A57E8F407A3B +472F731011A5798965B7B1A307E252FE02C8F79CEEDDEB6E165F1A94D7FFF18DDBDF79477F14E9E9 +3981ABD200FE7771B29D1D2D120EE79D28B9543818527039AC74085EAFF241B56D08220C958B5D9C +87C0C04A14D52AFD475B542D391BC54FF33DEF8D9484AFF6873BEED32DDA4B371112B523B6CE22B4 +0D1B416B64C9370F1CDF2C548F4CCBE9E12E21C36CC3EA52DA232DCFB65F66B22B5E2EC04852510D +5E264EE939BB67AEC4764B87062AEB7F680B40BCEE04AD45C7519EB3B6199C9E0E332661463647F2 +FB7EDF303EFEF84891CEBCF0FAC5F723A9D0476C3F8C092604C87FC69C7A90F4D64AE45A478EE8BA +2DF50FB93F55A3546123F0B0E2C1C40C98EAAE9F0F26B8F80FFE6E6B94B7E27D2884D58B8A119662 +2DF6BE608C5569D7864BB756DF2EDD184B90812B44ED4A32D001C31383A40AEEE9743651F7950846 +15C48E402DBC01C818D477EAC0347795CB2792E9C11E8FD4A02E194EED1C919D4598FEC003B6D9A8 +A0BC7D456047A1C0579453FC1D7CB2D158D466939A23D7A7B8ABED7E2777EC7487973E73F2266D9C +250CE30729E3C5223AD93B9AE8443B35711E446A3DC660123ED45CE1942A1A2AD0610467E081CE2C +8B92A6C82F0B17B5D2429E99F1A6268072C6B5AAAA6EB6283A872C54D3694CD825EB2926E57DBBC7 +C1663075E687A144E4D61C225781D80FCAE1497B442342B4A3F1CD6BDB50E31791CC3928C30835FE +F845B6BE5E2D7E3F2F5F085AA3FAEB45CAD0D76BCBB1ED859A9CEBB9F7457036F0BC3F195CB1A98C +9C8648F6583CDBB23894BC719D68C2DBD8003B10D08C8CAA40BCE784D7BFB4EEC9EA5359AC056E57 +B8B0F2EBCB1F4CE40C87FC7861180133E0CB6CE2FC4FE690756D327A2B5AE063E3021C0C0BD420D0 +56F0B941E6B36088A55BA11D0C35FD0132D5F48E5D9673572347171B4328D4807B972831C0D74CFF +A5638C145B89C989E6EC942148207D6DB82257585958034D9F9D4221C7C9F7013790DBD130F277E0 +BC88BB179DD09E27062379ED06F25EEA8B7FB33C35861A0034776E3813D2E9E5C10E227CC569AB36 +CB2D9DF2E7B7B44758F9DC4FFAD7A24AC7E9F47AA850C221048C3CB35A37CE8EA75632AE65FE3212 +175146FECD6334AE3D3C5F492F067F795E1E8FF386BA198CB74F0BB4DC0000DA383BC4CC3F070DE1 +7721431988D69C8B1A5AFDCCC83C22E16A87E01C6D3E79DC7AFA3DB0371B0866EFB8B6F88900472A +FEF1C4A878243C52D4E02E82658979731C841C489A6B97E271C4C93800EC7D91F93EB9B9C659A554 +E1FCE42A5EC65AC39190EF4B66DEAF6FC0569A000A9E1495F42F706FBEA4D32EB7EF11A648910259 +6A65CF899C2F322F5679C6D123469192A9BF1A7F1F2C81C554ADB97BD19ADB746A4F81A4D5559E60 +AB94C483DBABF6CE2F28CDB412D50FF3FCFA3B3DAAACC6A83CFED910CCB3B8D2C19590AFF4D75303 +4A6CE7F4156896A13808E0DFEAC547E69D3C886691728E4A35ACD575B40D721E8FCC5385A2EB28D7 +08101DC50811529528F5CB0C009BA7E3C88468E37768FB0D83895AB54DB2DD5426562AF9D8AF304B +F6EDA54E9C92643DF926F5C3578269750120302A37CB140A18BA56BA01108D4ACACE8FEAE640A6C6 +958EF156B588ADB0EA5F3B0F37BBA12B7BCB221C811415387B024B7076FA4403A3AD6EBB5D9C26EF +EBDB7ADE7C60B444AB9F90EA493B658B7767AE2BE649BDBB3FE85F460F1ED137C61BD95F7CD3D8B0 +15CE45138538930AB62AA0E54B4CE1A5EC5FEC0A2B28B345B67089A4E4AE14D2E1F5A9C8848DA688 +CA298F93860649EC3AAFEF3E820D86988C8E3E5A4D4BB937791827994AA3E81D0BB3EE115EC36D5F +B9A392D09E79AF514D11C7B3A03C9F9C13355CE79E119A19177FFDCA34704D38118A8976D1EE5AA0 +2D14FEB1414419F5E85244ADC5C0A765A522EEF36170064BB19FEE3B5F7B441E4DB967DAE0BAC2C4 +8FC6A836E0EF5A69F073BEE1699F55E9C757EBD6FD8B514E2B49D6333815B7DBD1E0694695FCA3D2 +1320A0C4B852D9706DADD8369A95FDD917328BE93DD33818954DBD2C212D2CA81560ED5BC284EB04 +7A5F389E24E43F4FA8C97FECF46589FA7341076555CF55B1C21B28E0C1CBB00AB8B6F67472F27BC0 +D11148F407824B0159B5188D4BB7386FBDBF1C0FAF34721B7BCB5C0FCB7C4010DCB6A1284E9D7883 +9E3C2111A05D29AB7997073B590A81C6168020F1D48951BC7D8476D5BA593F4F23CAC1F9BB0E091E +84B4E99E5C584D1370DD12DEE8DF16AF8BC6B7B23E2FEABDB7F32779AF8E2B5094A6E9B7A7225F24 +C43A8E5D2B977E1E19E633C26771E23017ED233DBB02C64F8CF03992C6484528D0C8464B46F24F9E +8380F385D5D01B8893C67FC103498983CF939432AA380CA576D09030CD52FD99BDC3BE16C7204CDC +3365BF76294A83A1FC14A236F5FE5321904E779B13232A76F8FE521F425562678436359C2461BEA5 +AB27209541F557AE2AA60009C9CA0A9FC7898C14306CE35A50017BADEFDECBBF94EE2905220706DC +806409EF87DB1D73EAB0698AD2DB72CDCDB293E7FB13C94D9FC87E74502E6927A212F0D7D2F2D194 +64F7A66AC07872E18CB1DDE8F11835DCBC5C4EF039333FFFC0FC1456DAADE7DAE3EC2EE0D3415B0C +ABB69FC5006F4D14A4EE1A5CA99AD4D5E629C0DD1E0F097B5B93DE2DD001A8C418234C9C45E8C13D +1AE04E9466DAB8CF1ECB88A4E059C111A6468D2DABB90DA79C7C79E94DB28F6968B1A632F8C57D9E +565FF91C6916026FFAC0661856B9FB8DE9C81661816221B1FC159CFEF1751E7E403F5F2CE32529DD +540792FC17A12A3DCD7C50D38EEAADBD10ADBF5D8A82442AA900CE6150EB7A4639DD9FB6E385B2FD +093493DCCD9014B23EB172E21AA89643A6CAD1093343D85D81261972DE0ACB16A4C6B5F0BE4C978B +FA12D3CAF0134F9EA49F6E9687C8F99A456745EA252F0BA9968C7F9586E3DD841AA92DC7705BDD68 +2DAE41518A09DF0E209F321D7FA3417202F4BA76A984DA3ADDBC58136885362F02F0A24EBC439B3D +BBDACFFD8498EBD29F88F016B1FEABC10785438EAC860B554525F3266097A675299AA0967BD3B7A0 +EEEE3FC578D1BE99D3533BD91571AED904BFC9DA1A1451FDC5406E1CD614E0C7FBC733563CD6CE6C +C31E9237CA153F1F0411114361D731636BCF98555ABF12848AD109371A42B63675A4130B81E97C2A +2EE2BB5D8FAE2640156001AF0F55D9D5DF8FF23C8AEFE14F120000F14149A36E5C94CD9081DEC277 +C2C34870D05011F99D48B0875A5FF542F067F7E9880109F586BCF2B50522A1F23ECE44349E539E70 +F84E207DC9BEC7CDF856A046F1A03226AA41F541719AD1AF88FF211E57DD0C1275DD0B7B47440DA0 +89B98C6EE92A7D94700B83CEBE19EAEDD8A615F6587587BA8BBA3CE3AA5E8EAFB1FB0F486BE3609B +169EFB178A4292F4C0378AFE5D24EED1CAAB514DDC66C696D8E37F294A6579131DDF5488E9436609 +ACD750C3DB0A940C84FE022B22ADC2676F62E91E8F891225F891FBA537679B24547BBBF35F04915D +20B11739F620D18B5B216921D222F15044368569AA302980B9225BB839F494588481B94B0C724352 +B2DF600A22B062561D86CB8F81514FBDAA4F8A043A0265F992FAB71FC9124A45B8475E1EF3DF6B6D +E35CF329777D45F08325E8505EC0D979F542807AE77E57E453525F23BC59A50740371EFA98678AEE +6C425374AEB745B99DDB5D8D908FDB551FBC0DB15832107BBECC4E11A1A8DEC69358A574A2ED46CC +31D564549EFF23102D92BFDCBB2BB985F78F36033E34F59C0EBAFA3BDD71338736464CEFDBA91398 +33995EDA4207BFD4A9867D32E867FBEB7DE60D132803EF9347CB17BD91315484EF6570892297DD8B +7D966103339535E28A00CB1EECA4A9775F60A9F5FC9BD8B06D78FE8E6318C31DA2E847E3F9CA587C +B01AE2BA0A2EBDE308314413F4F230A758184ED60D4F71F6CEC22A93A01B6C54E0449A3860FCA895 +4A347B7588329A80974ECBECDA1070FBC055666375229F13DD995E99265DF870BC8B8CC6347FADBC +1A6AF64599271A475B9123493D46BEC41289BEEB67EB97A8DED7A9C9730D37C65164CFBDC22E5CA5 +89D2E7954C7136EF4E084C43A6C7F361A3E96989239BDDB9A593CC2A80BA16DE9EE90E95CD39393C +212AB22EECB677FD36D34DEB46C4AD0D21BF7E6D7CBD0C8083842FCD87B18FEA7CECF939987E99BA +34C214E44DD84C176C9CC5A4CEA76D380CB316BB4EF9DE73D73B4AFD4ADB54451591DEF86621D138 +D5A0A29441502BF6C2ADE671CEC3CB5CAB903A657EB2D70C943F976C110E46C5D9D29BC00A875F27 +38E5D22496A43E096E009C5D3CB724B4CABB32838DBE527F83B18CB457E57B092C302EE557FD4F00 +DB9C56E66C9FDF4EC9FFAAB85F60D02BA79694FABA476A199A0331C30A78A92E10417BA236E23364 +8174C826331DC1BAB87C5F95027846130C6A2B4027930EBF9A97BA1B039D386FC51C302648E25980 +212F6A582CDE2778C677A01FBFB3C5D1B8A374ADAF6ADBF7DC94075F25ED66D440B3922C5F255FB2 +3FD8F6E21EA65B1D93BB225684B50F11310E242B087575973345B229BA62C1E2C35BDAEC04D10148 +F5B2F3BCF7399BDFDF1F3F79119714AEA697245BC647316EA157484ECB951BE367234FD02E8B1F09 +1AAC3D29BF282DFF4011BC0CBA8E55234D943DB3017CC7A766720BBC29B2D097A956C0F1067177F0 +12D42ADCB473CDE8D1BA35B4030757FA1D8211989DF3BD22CE5D501C21EF8708FB3449DF47D88650 +9FF7B59B76C0DBAE443F336FEE2D615D7EED1C284F14335BC8A26BF4621E10DE9611FB2F1DBD52E4 +B7565D8C65B54EA36D508BCF0C578A49A2665227CDE1F9768EFE847F9D94F1BBB7DB83701C232198 +5C7283D47B2E40B27A268428AAEFE75F6B2F8764A8494E5827573758CB9CA46FA93208836BCCC8B5 +564A69F5AD882052AF1C1417C3FA7F580569528682C77080F3688B65E7FC24D2A3AEB61574B4A321 +5927281544DDD7A6EE0A3E9388F8F631CE7251724DF70726E5912DDCCC8C652DD6C9608F8462303D +867F589DE0F2F71711B35142EE6EF93B64D6326C4DD7DC83278E057100EE772082E6BA368ED91A55 +53ECFE2293A481E42F83BC8F9148C70EACE91F7B7D9CB8A72415BDB3AF66F68EA733A17ABE9DB005 +3BF148629132969589F38D30EABFA96A01FAC72650B5A6FF3935670198A1EA33810A9B11E330EB8B +451F24F93544263436F669AB5A90A53B16CCEEAC36B1445574EFA7E802DE73522BE725E68704822C +B7D3912717333367895BBFBE06966A5CC653AAB5E9B3596702086BF0010085B900711932A95ACF15 +CA4DC45A754EA334E9EB84D6FC8E3FC4F897456BED64BB93B593549FF0D5352275D8E417172A6664 +C5E0ECED1019494A7ED49AB0B965BEC1A82E5873766BB38D7D856049CCE2FCA65AAF61E961B60634 +E2A69EF059754C9D8163D87F928C222772D070D83FEC6FA5AC734AF65E40BFDE521F7D9CB1650FDF +64754BFF21EA3FF0AF7611A93D525EC9B28C51AFECB04E7FC8323DD6C9B0D8539A34FC3CD8CEB795 +8E8EBBFED4313C77ED469C199552A9FF70BA5423B03B6148D4EAAE17B71C5B39DC436AC53D6BA8A7 +AD81AA8B02335A8B2B11E9F4FA913159A725B8AB60F52F1A2EA50EAF4D56656E615BF382CC68A690 +BF83DFF24FE986570ADC0290ED1A37C1C2AD469CE789E0EA0BB5CE01020100E729721AF3B5BADD33 +A2DAA6C33EB8F9064F5292F715F820B4BBFDD56F76D42E7A1A068C1CBDCE4640082F6E7D582D1939 +990CE6EE8D270015A2C461798B37DCB5798EE9F7512168B76D26C28BE4A49A1BF96C89D235F21A1D +B6A96E5DA474D0B19B808D13D7A11BF39EA8647499C410ED9894A1ADF33D41B6FC2E614D8087F4C8 +4E437B136F3CB32DB8393C49177A0675A0C9E7EECEF448A97AFDBE840FA01FC7E5F2E8FECEDC1884 +84C312E8635CD79195475DDBFDD4D38D5A0246DE2C7F21608F8D2C0DA1371D302E941572E5792A3C +F4E51A33228B93A814D03FD4FC223C314CF3714BB3A34BD4F7ED6348577FEED9DEB082C4049E57B5 +D3CDB7F26629E9F3BA36893E09E3C7463D02A22D7056BE76B87763260E46E48BB832B7EE13F8DC05 +37EC8E81E9BDFEAD8C27EBDF1AD706933EFD11131E12814F236EBB01BE85B7F1B2D627413B324918 +D247604F56EC128909873FEC3857028BEF76A3494364C2A7002D104D486236C30B48E2B75D851C34 +EA50BA7FFEB4E19190898AE21768C157C0CAC628A2181A32796FBC1A7271D2473CD88E5395DDBDB1 +FC3AA8DF0F3D588637F19A8B833AFDEB5F655A8838EECD684E2315B72C75CEEFBCEF94344ACE8D6A +DBE355008EC72FE7CEEAB01363A895F4E73F867639BE0A0BE67333848816B05B419221BE8F9066C3 +62C23FE85B7F392930BFE4C12B9526FF2FDEC38F23A159ED61A0718E7115C24597D849FA76369153 +54A40C965D4D72EC94DA61A03766AB39AAB684E134FD1407A5B1B19BFEBA52AA0DA5D99CBE5C82DB +AA663711E6DEBA180E1D4A39C320516A4350D296BC19BF1BE054859A0889C7E9727A021F3176FE62 +0FB0C837E4141FECE531A950C03D319E3255703220B7185BD20FE5DBA673F8129AB211EFCF36EE39 +4C7E00EB0876624BC840FA86E58B2F584754CB6BFDFD76810E300741EBE4544E5AC17413ADEB21C6 +2F66CA4F075C32381796BA709782DE34A675B717A2C7F6D88104CB924FDE5DF775B4F0B68E0E2E5C +2F788BBDEAF06D8E1FC2105CCBBD5827C0B03FD6CD64F0D073F3192D5F94839644E5EC6C5185BADC +F04112A65F49A8C83174A9AE958E76A2F5AF469E8B76C833782C5FFB8BD7B1BBBB3EA0CB7C9786C3 +BE2ADE5E7AFA8C8F20892659A59BC421E28845A108E34EE17864042EF587A6D67DECDFB3F510EB40 +D2229585347A0035670FCC76C2837A4E4D68304FE113C539B35C1F0234B5079B8E32934546982978 +C5E4DF955A454EA263C3CA5D7101F31A318D82A3F9FCB5A8AFD7A65209663B0FC9DA400B26F285EF +46D0E1EAF8ACB1F1CB805E3986D04BC585073FC64895E4DAE1CCB749BB439CB32EA91176D5C39C36 +50D10AFB9C9884D5FB90183424CEE67EF2175D01D2478D67511EC9F54F88763C152697B06D948BED +49240096EEE3D06AB4575E8E8B2CB8263B5BCF4FA1608720F52B675309833071879DF52C3EC2871D +20F398B5CAC8F8A4D41D0F1D47584DD90DCDAEA4A1CF160C4B3BF1AAB890B5CEB6CB3488672AA68F +BD938281DBC1D8BCFE92FBF514DA5358443CB6E0147254E91B38CE6787B2BB0DEDD2D38F5938737A +977B5EA42892520C58F8FBB53C994B57382379E9490F0D6970B980E1BDF8CF9F4C3C5E0A18F66E86 +EE93FFE7FE546DE50F41364BCB3721B637072571FA1779F1D672FAD260C16D7F13CBDF3E4376E7FF +56D2A710AC5AC35FCBDBCE2C9C17E523BBE6218617B13C1FA6679B308979AE7C61DA6E68369324C6 +CBC7DDEC364E5A86707266C0B459EE7B2C03FE584E529BFFDCE98C90A2F3D9305AA74D3ED8430DBF +3A49FE2ECFD9C4BC9FEFD22618FE9C8A973AD072AB6F713E4DF02DCDA7AC5359B2D652013E131B76 +B3ED6C75FD53BA58D862846264627F6B9E70D8800F6D9B32242B747A67BB2B45675840D34F852AA8 +062FA6B01E31ED24DAE02F6CF788A17F7B9368175195DB0072259CCE0FFB2C1035C1D26E1777CCA3 +D56A827C3242069E76D6DD69B653768614B9ACFF16567FEA61508D51454BC02F6C60F755AEF6AFAE +3536BBFA1823F8E1A53C41124DE983E51CEC92AEF4F99785D554488A51C20885346D1F761DA79017 +940A0C557D93F1DB6B3D00FFD61D08E96FF3AFCE5FEDF545CC9F47A2B1BB26713431D6D1E47FD6BD +6E3C668B0368241F0EBB5FA9C991DF79890E52E83A3675EE699B61BAF869DE91F67278F510061C6F +E41DE2D883F48CD0E068E2A652B244128D82E5CD52F35F210DDAE3054691ED55A7D99088AAE8FB04 +F525C2084AC09F5EDF80A4EFAFE981F74C0DE9D194320709B3464F3FF2C0F6AAEA6D973D9C323F53 +DE3D741F698FBF01036716BBD62957CB32CD81D3A2674560FFBC5BDC5C6E4F547E589AD0B1CFE14F +5E17FED1C4A8ABE4E67CCF8A49F32C4C6044F1431E1CC382E7758722A6D0DF9ED23E51F8AD14D11D +7B6428E27443715EBA4E9C05D6F238378F9498AEF0E7EE4FE6856622CC8E6ED141EE5F109E343CB6 +695C4BE1E0F66601C27975983BF557C04ACFC19227A1AD7E6C44C00529FC7EDD7F886D24B7E029B9 +C395260088BBFB96972199A7B32796D27257DE83A7402291C14FECDF7998C5C96B1EDADE0280F856 +8A8F5007852EED303969180B3329917973C2D32C080C9765B6BAB0673BC7ECFDBBFBEA980C263843 +39B7F1052591D91667D4FEE413AFC23DE2D4B9DA742F4269C6C939F5FC32A38040730A018155AD73 +3F231E4D5B9D01C03A58EAE7B5F590CCFAF25EDC8552CFC8D95C60EBAE1837D7A97CA137E9D4A4BD +2CD34AEFD68D64B3F4F62326AC429921D7FB3C235184FE0899690A0B775F1A566EC29D5830D32372 +6526F7E7F5AFDD71B77E07613DDC4FC63EDF49051AEB59E6337AC0A4B6DD872E776C9CD0CCB86130 +5322D816732124F5978A86C186BF0A0F88E733CE38E4D7C1BA5378C5629B1EFC97806059990ED42C +5CD183BAD7E94070E4058569DA2E51831FFE0D080301AEAB4350BA290318AEC582C78D05DD92E5AF +B4424EA808629BC972E68F4FF2489C245593F07555CA6A2B25964794CF31CBD3AE5C229AB9B8C298 +06C01D116EBD0FF0F159ED2D3D7DFC73EAB4910BFF5B0B0B587CD9EA6E6FC45D63C09766224D8346 +1F0588140B258B1729F70BAE7962189B1554483392988CF230AF4077193E53330519394DD99BA135 +6D4730AB221DC6A66019BFAE564893DDAD7B177DADD16ADD21D396CFA6C3DC818052E2F71149FD59 +4A16DE0C2FFDD366C99B486C55A6E991E4D22CCB15843F0C3363676AF2F5B2D1B7EF66CCF2F12DC5 +0D63776BFFB058D70A9C76DCE96C754872D72C82A0C33F90D49C935402CDD26B6D743B1F43BED5D8 +B539424849C1495DAE73044E885A7D0F307F1816DF6244A6F2D97BFD4E200E93F69B08AF39EA21E6 +E347A47CEEBF803F73B978ADBFCF056789BB8E6E2563DE87DD9A8C877157B934102DCEDAC54D487A +1BB2694F0034093C48F10A17D32E2BDD0C723CAF59ADDD1BE373AF8C9BEB4415AA5AF36310C31F24 +354A53C0B962573148BEF91D994FE3F3D8450DD4D686725799F53C373A0A3E3C060C2E1A3E800504 +9F26D716E1F381B9F83125E4683264A07E2D8938F605978E2513DD2050B3D8A1012797CBA8961632 +BED260916338A812AE751C7B657E086A0C7DDCD3BFDDFF3E48B84751925736D1310C4910FC114387 +F3ED7FE163F91895EBF55FCB425CEF5729D99BD8F2C072E36C310523E75CD8E5DE49C031C4263410 +9D56E91A46C8C8E89FD92012A00C33D0DEC52597B5C6933291A7BDC5CEDA95DCDA5600F9AE1C8250 +54E7EE1067458CCB66610704C58E4A4FC0CB5FC933D0322A716B2CD430A3AD48DAB3D4CBE9D23F2D +092368CFC4E1F5495C133A92942EC62118D45C17723646E69407B4A89DCDFD2AB3FFC099A21D9D29 +741D68270629AA3A414FE58658DC9170C247B6E23F35C4BC5FF83009F462F2EEF4DBAC5FD158A658 +57F9B6DC1F5192DFB169DCB65621CAB2F1B07BD22F4155A8E9E2B6388D430FDE5EC1C834D22EA035 +C52E1E34482EADC36B4CAE902AAE89A7284E62B3C84B608D6BD05F75BC31310B2DD3B2C08A00E073 +7F104F03A41989D5F6B9A2C38B22F1D1803EE5D7A4D8DE44E4ABD496A1DE0C0E12C4BC96D0122846 +3F0EA9CE9509FEE987139F3DD3F9D0DF4313F555BE85433718F6D05F197C41A9D9C7A8B0D2740196 +82D49F58DD5F66B12A6520D9F226D1DF1F1B65CDFA261F980CA25A92645B86B64606293F8BFDE364 +C47D2AF2C709BBE77A70A5712F2CC26F3D66F5BE2C307A48E6F887F681D30121E32BBD87271B5DC4 +615D28C309F15AD263FB37424E56DDA6E17B998B45BE6C7FC6C28E3394A8764C9EB2DF5C06626593 +B5C665D550D4600172791CD208AE9F37BC082B0B242B0A504B751B18F4D7495172B697EE217834A8 +A4FB7CC16D6F9E8BB400BE8AEB0850960283DCE725249FCC4DE97D9886745AB6066C3E2F64DD8AB7 +9AA11667F11188D7965DC11EB760B772E282DBF13249F31986AC6898FEBFE23E3E8B8D2C33E00EA6 +FC493850ECB2E6D831D1EFCA3C2EC8EE2E394599091ED58BEDE97D7A43B6F739EB0F845EAC1DF6B1 +EBFE876009CC5D804B15ED4B56761B3CE1AF59C07B49DC798A44532297AD73D5101ED47F36A3678F +818297CC27F6AAA2AACCC9AA9B6F5459911D8C56CF499E390AE607F3790450B2B9C9BE0F006EDA0C +715B5CA0481734CFB0597478E7602B0D2C1E4F78F03C68C17C70E4B42D7D2D3C95CF40F73488B371 +8E2CB05A549944D86944D78724E266C3319AF89AE430E777E95F0D792B1C654306E421F3D63A26B2 +1E74B6E8B21B2E2B9DC596D013CDA16D08E65E8F24A84B12B2BADC653E6E1110DE2E709C1C1BED13 +707B70A421B384F20CA7A9A9D20324DD383F28B2D3C7A9C53F5D4C6B7C378D26DF11CF55238BE1B2 +4FA70DCC178DAD3D35670FE4919085EB1CD905971D76A368FDFCF9D2F0A23739851A3A6D2E02D65D +54DEE69ED5D81315D3EA5E356F94EF256DD267FD1E1A9EDC9CD63E743F299BCC4A4506233B8DD765 +2CA067F741603F93250C087D368F9E9CC4CC1A6DED567487C05BAA992B0056A77F630A72008E3946 +15A9DB24FE56A956650EC9DE90A6C2259189440247970541CA198748928215C0E132A81AA13208D8 +63C1FE817F70CA573B54577D10B73100AF8EA088208A44FB92ACA314AE5879706180788C17BB1D0B +81B6B95A1C4E0F9EA66F9B39BFE12444A6446691A7BDB03E0F03D9F07A10A7598F2166F108529F34 +CD90E601FFED3479ABCFCBDE8F051C348E48C61D95B00C59EA1287423F05666C3D36288844067E83 +E14F6B5210842C742B89F13ACD126B9FC50ABE2CA7D7ED513D43B6AC7F41EEDA416BFFFCC5C844AB +2D23D4DC09B2D510504CE98D02E72020D9E669DDAA344C63A1B75632F912A1C0DA3885DA4AF7E243 +E4A4C6493D6595BB6D56B0359106957259E59E336BAAF35BD1CEC5CDE735272EBCCAE8D4904AEBD2 +B32610C6FEA2B69941D6542ECB44D71092A3CF067708A3D087AE99FF29671AB7DD8758759B971A08 +AE1BAD78270D2FBEE37AA2DCB119D72F6C7B0C8509018A70D0B0BE2C6830EF8E0B24B1CE1141EF87 +3A4D7DCC501F808BFD94E4DC0F2915AA023076BCC8006490A43685EA25AAFC187302EBDE7FE1965A +04A5A398985D29F08E085127B56B057334D88EB638A4DDE64AFD204974C3939536B1B66A54B4DB81 +151853915718F70813F096CC1B0EA25E363B49264C2AD17158A4489F91453FBEDBDE15D7B74D7F98 +E81DF23251785D58295BA297F295AA6248A912CDD4F1111E6B628EECBB5139709E76EA4AB743CEC8 +26621D08E6BC64691CC90B3C3C1778931A28D3D5B1E20E96C643316613FC487C9B604C43463FA453 +3BCA1236286E6F5A6EEB2F1D9C34BDDE4595495A365F88055D9268541CF1654ACF478D384A5496A8 +772EA1402751A093582A6625A0A44816B5FDBE166835D598644296249B92CC90AA3FD6445C9A19BF +27F59CB0616C7306070F33C7DF4E1DE64AC8C5BB2FFAC1EF2B1B30E5A0275E6004CF64BBE2C6710E +DCFC3AA4ADD60106334708862FFA6652825BC84842736E47AE6917180365C75B27505EED3C6108E9 +898A780E20C3F606A860229AC46D0471ACA0187D6D539A1B8820F620F72B41AD1D3BF3834BF48CA2 +AFEA8BF535AF74C4562DEADCB63D2F5C7585722B77C989342D190FF926C8A5263B4F25286F99CF6F +C62EE6E2AD61C82B29D82468AC10FD27764278E5558CE8B41BA111CB2F040914451A480C93084237 +CAC8F66BB7C6689F340B8ABF0150E06D5B1177278A4C08742FE22F42C28680F190900344ADFA486D +59718C25D37275BCE4DF981AAC35D2C7E85C72A0188B8953CFA516FD545AEE0BF4B8BA301CFDE214 +4241FBDF3D204E3D2823301572E23F204C97305A82401660E12926EE7BA6EA1A81FF5C007933AFC7 +3266FAC4C134ED818A48E7DA01C71A46335C845F9DA5E960B25339D551582B375814148D94CFB781 +FC56093827B78578A73D4FF67B6B87F40CFA5E3F4325D9108CDB64BD06427B88C84105187316FA29 +90B4E3E8EDB6C78ABF164F4A9717D523794B2FE772A04DABBE688CCA977090979B5F47CEB90A1DBC +167D305EAB231C9F4260C4AD10889CB785169902FC0BED78DA15B8417453BB65856EA0BEA5245BA0 +573F623D215F6C0CF801851C305B355D26B52B0B343645FE25C78A3526841EDA480919A1BBE5F56F +C10ABEAA3E1FCCA7C43EE560F067F1AA2AFD642F769D1ACE8E2AAAF38850F0D757CD808C921D716E +96FBC07DA7860DFA70CEAE2888C0ED3CBF9586443532B68DAED9A926655C157A416C383A53D8F283 +2A4E67468112A09ADC837ED8EC95F70852921F50D4417239FC42EE3624CA97F682745CC5E76CC7C6 +7BD99F2180F8C0B7FB49539C8CC474C25C0DDE491671FF329E51BCFA779346D4686835A3AD6633FC +B5E0F67E0CA9CED8F215BEF4D240453EB2EDD6ADB22278AA5B985FA140C9834D38753DF2014F8C0E +E6DAD19E8FC54C03C1F6CB0F858986691D99592562CAD95FA0A5B2ABE4A8B54B457D42E8C33A2D19 +51C0419A72FB94FDA78ECD92BD2A1416459E9DECA9469F35E4C47DB531726DEE8F203D7042EDB32F +025DF3D582547BB1D45F7A5B70D317DF4EBB16E36B0D798E0932FD2A85B04FD67143E4B287A50416 +2C1F5A037CCD780088C5476385AF8168E12D97D44B0630621759173C8F1E3006B5B1C6D7138B7EEF +C3CC5F54E24B2C3CA7B41AACFD25E554880AAF406EA4C3C6E21D3B550B040FB1952598A7E8E6488F +E38288B2AEB6C4718338598A2BFE4D2B9D14C65732DA304C16FF3E1F8F03046EF095B65FD609DA87 +EC24A69278BFE65C905CD0329F6A486B8525B7EEA4F7AE56C2633CD83543269E8ACD6D71F500D82F +DFBDE7F7F7B1AEE67328549232E26CA55085B6E84D9E2E7F74068F93A90C4654F2F396E57C5F76F7 +E61CBBE523DBFBA6E76638BBA3064DA025A79E3A294FE7F1CC28A3B4C57DD6FDC48E541A85534B25 +E1BC11B4F78019457239EAEFD4BE9007D205F1D985F389DB22400B279C10948551A6B4A17FBDA0FF +C9428B18B43DC76EFB15FC2182216F1B60B4E344A03AD6C00F141EF99F89F24C819C3E32877A927D +84C2D006940F39CA8B71E5951673EA9BFD1749923219DE38929ECAA9CE43B06CFA7DA1BBEDFDA56C +61FF6C24F40E59B13870D5FDEB82D981154FAE5D6D5152DE69339359461A41A9713B6BBE47E868C9 +33CD74C75DB71D13BAE4DEC85E02FAA14EAD6C0A253B16C79514657B15E68CCFF9EE6AA385CFF9E2 +C53D9AE40F85C793E4E8FF50B2B7420F4FE69807BC5F37C3E300E6B3C3549D1D3246A2E70F091054 +1135BDF805E0A698E236B6496702D061241687B7B8D1A0E517DF0476DA09D89667A7AB375FD2672D +CBAB8124E511502DDBD08BA04D941DF1CEBDCCF7ED48405CBCC33774A68C5212FC6F132641FF413C +984F8B43BDFD7B1A2A3435F15AF07EF4970D3E4A0BB947C181E9CA27CC14A35BD1BD096875B45873 +8CA244F88C28728B74E25CB8C4FC1095A56CA75E4569AD3082EF194ADD11350DB3B74B96761D4538 +596FF7243B1E1B724716A144106E080D42036444FD472998460CE9ABBD05B42AF9389AC452BDBBA3 +A13A96890025789F16B9D92251FD3B3BEB2C61EDDB370A20456E3BFE5F4039E2557C451C524F8087 +015BAF3FF05F51869FB97512968BDB2B49589C1C7AF1E085250A47657465F480B7023E24C76731AC +0EAB6704123D77977D3A2C4C56B691346EBE589C619C04515D34F81FC6A17527D5D8319013C5D4FF +27CC3925E24C99231AC7FB9EAF0BBA482D3B75807AC85D03CD09DE5D9AE0B07B7A813F0449786500 +0AE8A7E00080300F0AB8C399057EDDBA273DD2E1B2A0DCEFAD3B332E6D4AC1FFAD846167DFD70E03 +46DAF84AF292D4F424256ED5AC4E104F80697050D50844A708EAC9E7F7784FD01646F3BD0C595CA5 +1EE6BD607D254E78ADDC5E15C3B6AC4940EC865A5C23105B6BE09EA09F2C05D6D76960A843B81EE4 +33977FAAC3CBDA85CDD2F4DB7C28293A77825635992AF8F3B38B4480D9A139B1662345A8ABE1634A +77496C3F57597D2985E9E54717AB2E99CA35789441BCDDEDE9A9E2106B401D9684ADBEFE40D607F0 +75C179E9CC03E59E65430DB70B441D43DF03F2AA6FF06F224B6E455B01C64FB89EEC9103E48453A9 +749B4D602808C7E408A8903091D85E06AAF635D0D529C3CDD1B8479AC0F4208C284BB678A547F2BD +77BB17C86D4560434F7AD1937760A6AA55B614CFA9FF8C9C96561AE6C8F2121C4E20237428BC51DF +2099B6C49E3EFA18E6D439E6E6981E746EBB1DC461259D8EA0F8099C47CCA27B2D982B72C9A07CF2 +1B3C05D6E26E6E286E348B8944078E24809F9C5F3D014B4CBA02533F5621BFBA1F0EDB776C634746 +703C9F73BA89B1960A496420C68F54E5B901A6D733D7ACC79F275FFFB253F389AA480084468BB34D +A1E797E43B7F6E8CAF5E8C93069A3A2730E57EC39B677BB73E3F07C2055599F7062E53B37A5F0099 +907D2ED87FF7A82C95FBAEB888033BDFD67BA3A6031A4CDC56CB1E4CF5B06B46E16D988BECCEFACB +9E1C037023D7BF5CCF5D65AA66A17AB361BE7981F132A578F3ABFB97960A6034F052D9D5AFDC0679 +782EC90F240F943A5F9A3D969ED7399254FF67D89DF668F7C56FCEA1FFDCF20481474AC8495D3AF4 +B6D7EE093E369C057F0B70858220693B398ACF8E8143558132E4391405E30A73937C53402E459F4A +A3539CF7A99A3F51C0307D045DF8B77757E92EA2F51BF0BB4F77D3904DD355665870C2B59F1ED7F8 +4FC71FDD7F0B6C5D3182DB77827CA6A2060D2B8C83C4EA4A432EF43A4D0A952CC6CBBE52A9F0CD66 +1A538973DE41FFE9C5CF55F2506B9EFEE51FBAE5E63BDCF5528499A47C031163C88D3022606784DE +2F46A9C9235AEE3D4F71D4959B0CFDC5B7E78C8C0A8F9DC99440C2263DBACB343C5C648577F5610B +50EAB1CF7FD02419EF3941C7CA0B0E64EBAD4B2CB05A0793DBC38F1946D44767BD287F5E9779C611 +CA0DAAA1E7393DBE0683C8D3455CDFEBC0E64B54B737E298DDA605227C0C4BBA87AA3EC7FA6EBAEC +39E6EF2537D5974391D31739D9FC42983D81AEE44711C823F35F8E2321AC74943871739D2DBE9748 +FE68592263E7713F27E0D49B9B5CB7A4E55DE54E6B800D15856450FFD3AE5F287B12AE4F438B20AE +9E27E6CAA00F3EAEADBE08432684FDF9931E925544A680182602A3C1997DE5D0630BD5A010535E66 +E1C123013D23966B3545C7431C39B97295BFA4099D14461004C42C85095EEACB9B47C593BC6DB863 +533A8619BAE09095DE8ECA432D4DDD49AA600D277E75DC3F5C6631E2A05382CB007825FADB77438D +CFA78E252D79B6A196D5164C2FEB85D75ECA25FF80B1D97FE10E87960CA0FC47C41D3A213BF141B4 +8BC3AAA93FA86245064668394665BFD52D12C3BE4CE39EFD8111754398A944C3FD1AFA98EC337BAA +AF899D35E804CF416AD7FE45FFF13FC6354007501043F98FE8428DE8013901BA6A28711A2CA85A27 +0BB135B72F1D5026E8217581860729E94F2F1878A0E96C59E9F62714FB5F8F25003DFC7347E99007 +8A9A331CB3A6A535BC61866F02513DEB982C4A13ADBFBAC3FF70A7335F40D5489E48E5EDEDEF1619 +1973D932479C62183B0E25EE8C4F76D4F1AE45DAEA4A12AEDD9EF81D248E8D19F8C8A5BECDD1EA1E +98783EB7A38149170851B1942C96C53DE06DEF80913BFC04E539EC67C110498D15B78268853E5C72 +F485F8A27B768569E54241F6115875E2973292CF48FF91D45EBED627AE9F0766D22201B20AFDD40E +5B17CF337F2999E0BD15B86E46EB3C18FC12B7DCADCF9DD50C6C7E3F37E615A892DB3F57E250A072 +A49F7277DD6A2C8042698233D35A699B17ECA5DBDA6D250ED4A16FCC893BF0DC2E33FB1EBD7DEDEA +3C1C39603C8B7E1A5A833A8FCDD5570BD088749BB232615366687962C7E56ED089CD7B092505CAFA +5A80F503C4CF337F07ADF0D106937E25670839D491F7BFF7A523DB609D126328C16113ECBCBF9C40 +04904427A108618AE5D4ED809F8CCAF72251104C94EC5BEE21F91B179D31DBA79CEEE5EC7FF698EB +84AB1D2D1A624F58B3622A78844CE51498B2CEF38EAFE259D22C7BA61104651A862008BC1DDDA58C +C45F663EB26428DAA85E7785363A69D2790996EF5D9621D53042F42F794962FEA46E46F37B8AD1FB +76FC8D5CF2146843F8CC625139C75FB42DDA71A752BAC48F294E4C0C8289FC46DA5EFD9C91BDA6D0 +27518B7E81E8B21F755A9615627D5812ACA674D1527A1185EED4E3C628196E7D0759B1CAE6B9B7E9 +01E9599A65230F1EE469CD33B9BD9C104C44E3C1AB966C9678BD0AD78111A4E0F2D07A01A038CEDE +7036D0534D684A1562A17AD64A00F279200C0371B1CBA61747671D2A21D3F9646CA290F6B82418A9 +6FA177C6278277504B7FBA936325F5FA124AB018A15DC18D2C5E8F93CDEEA52BEEDB78A57828D81A +3E6C38B9FAF3DC4EB7273ECE3EA4482A1C6242A335862C2C3717F9C9ED95F77B140C4E1569B2192F +C7DCF702D0BC9A50428EC406F8BD0CAF886B4D979320D3E429816D88F7C7146D960AC12E70F2CB7A +9F4E3E366665AB3F1B4B6440F55EEA26DC9EE0096BB7763731740A537766490C8C174723BF0EB40C +53701AAD12B21D436ADCE22203C1053A9DC4E9F17AE617888C4B4E6F3A720E4E6366BA628221A387 +D8AB15E04AD69387C310D3528BD2FAA5B22BFF3FA494F5FBFAC4F771C9C7402B95580C5AC4BB3AF6 +92A70CB2C851FA5CF1173EEC3EC29B5A05A0B728BBBB51D3B7AD8B0AF17A1563E82FAFD93F8B7118 +1FB7AFE352874F4EC6D334AB6747519AB8E847B7BCED33EB5458A828E074E74BA621BDCD03FEA604 +7F7B6ABDA01FC7514BA1AFF0D4D0C0CB8F4E42D5A87E395D9ACDD02CCC220C157153422018725846 +009A3ACD8C8CDDB66BC6836B4026FD9F526AA275D06C813179E5924F26A25094E7BDA8BD26AFC4CE +B41D8964D4FC4AF1DFB0595BC5D6714C32F15DC7194E9A3A73013C45D8FA55CC0550A12D9AAE8E9F +F199FA28EFC2426D8D1DEFB93A65717AF3EA8E2D5B4AA8EF0EF38E9600F7D4E7D9F1D67A2E63ECE4 +789FA74B159BFE2F91C19B0378BA52E93DF12830D99553B6618645E26126842AB70262D96E35E5E7 +50ECA0CE3458B3E51BEE2F21191136DFDBCA39BDC07939E521E4F492F392DEBD029C1EA237BD89AF +76BC89F618D530160AB16269FA6B693CF14BDC4EC7C630025703C5337F61458FA09104EB15C7CB20 +AA4C9BDB7CEF3A09F25BC7F3149951A7CD75372993B80CD2112F7674CEFD6AFA764AA3486730D2C1 +897A264D82A91709FEC4A21E30D812F558451804EE6F3DEE2C4C437846BCBDA07C5B6CBA1D94AF02 +9163B7383CAC6E088AB1DC14ED3743EE77E26EA7AD3119A76C0B5F925C4DE305CD7BB3A09A453947 +5B9BD79BE28FC462D8718CE05F9D94CAF3387BA55E6E447BF81A9EDDD3A34E17BE66BC52B0C0BB6F +86F6F008829173816D205182ED2ECED319864A796AB65D4E3950288BADA94FA32B6F453AFDFC6C39 +A4FCFE60353A64627E2057D4B379D3240012B3BB0ED0C7876CB83C1BA5EFB6E2A03F340C2B576731 +F848F762A7E1CCAF267EE06D621BC33FC245D0E1547ADC12CC0EB58B26BABDB8EAE9CBFBAB93836F +FF22BDA1831DD01B7346AD377AA298D84628BF1C07433284B0A90FC89F5AEB2651BA2CEA405D4F52 +DDC0E74B871D43F71EB4ACE0D2B401F9348EAC3A2EF0AD295036BF6CF6F870D58E00B619D50EA7DD +77BC28DEF91D805CD527DCBCFDC16C042BF9B874E3B1567EBA4C1E70744B9E7E5BD1FDA6A5FF6E10 +1613FBE58DC46CFAC1A65ADAF65E49757E9304E2AC9A91E0588600C709A61D4231730073A36D473F +518A145E141D0A5A494441B9EA99AC23F60F54F8127B477E1CE698BB4129B4B1DFEEDF10D9E665C2 +47A62F112F5CA30B0AE5DBF3E495FF06EB28EB438CE8AAAD84D5F50FB56A3AF002C23BCF66ABC270 +7AC233FC0F2723DB99D2CFE7D3B3667732A531F5DC315CE74EDB9050BF75D29E6430F57CB6778B2A +CBD57DFCEF896E6766C8FC5C9F9FBD701CD62CACF33EE0FC95E78DADD205B5F42CC63024624BAA0A +B4DD447832B4E1DBA77BDFADD223989F8E958C8D759AAA37930664C6EFEC708116248A2A7AF3D656 +DDEAFD009B7F5333854608E67E5E588A857167ADF9225CF6C641F5E19C3E08678A281199EDDAC831 +B57223B1BEEADFDCBC8F6F25D32FCA2336C808162E8F381656E847FB6CB13969572425AA05AC830C +33DE6E030F86A3A85D2A66A77F103C7042C97205526DC882EA9A00EB8BD5519847EB424C15F808A9 +1652A6CC89B66A5731126DEBADE123C63D88A2E550FACDEB3886FF98646000C64B3A91078012CA30 +904B71737CEF6BECABD43DD702880538F5A70085E6CC6015D2163681067C3D513A8C66032C34A0FE +17A58AD4BC97CA69BF41F11D5E910FDFE9729652D3EA21F8DD8CC19160A8FC77573B1E9CEF4E790A +79D8AD6723B6804E9616466C935303E063DEE29CAA6C3BAEBF278B818C2EC2F13ED645AB452397BF +00DB8B26E115026E256746CD0C78A959364FDE6DEDDCD0F441A61A1EBA32C7BC172BB09512148D1E +BAC9E791B7D51B71CAD2DC9B83B2F99B3726607D9CBE58B499A13753CE87FCDCE21C0AD0528ED0EF +B9B2C927F57C78C626248AA2B835A0791244C5896686A66173EC9F802C4C633A42B086334D2A4878 +0E53D00809247BE64E529F96AD2F8B3922A6097D414DDE1EC76F9552F9B8D58B8E34F359AD792B2B +E50C26DB05035E7497162E7C49C38D3CD9B98D620AA67492BE5AFCA3A81A7080185C7F0B5105223F +1FA77805502A2E8C5FEEA27699858D84A95842C5F2FB68686D59FE24091FCDDE139B6463BC6C7B1E +0E90D20A83651AF00C85797BB9F53ECEC1675C7EE636D0D9E77DBD8F89670F855EE4D4800FF3F695 +0EFF09BBF8A0DAF6B8242840CFA5BA73BEB95115F4A78BCC02D85ECCE0C0F2EF6F328AD1DD6CC049 +5A3315B414A4D61DA50DA46D7ACCEFF6EE56451805D26B0359AF193531F95F6589CEAD6FA041AF15 +3067F88A0A2FECD135C56682DB2B45A71D1FA737C064EE9A4F404BB72A70B3AF0330359393247EC7 +81512482579865240A23CD8479F21C2C44A119EBC4E81B308DD8AA86E60C3DD8ADA50E0DFE8308EB +1A7F201EDE8DCFDA405AEFB47E0E6CA7DDB376DCB21D37F7ACC4D3E9F26B03A8DE0E8940CA3A9E75 +963A389DF8038D2C486072F61C0CEAF500753C7A6352B1CD0338D9212B42A4D3DA23D5BDF44C27C9 +4B88A415A3242FFE2E1B332477A21D2B9CE075EE479C6E657A4D8874A8C53964229310E01ED4F3C6 +86FEF5258EDF3B464DD6FFD7F1CAF473BBE722D60FB14AB4918E93878A8AE4773930B8CEE110F476 +7F42A52D9304C55BE12846C911A10AB9B2E036BF9DFD597F5348D42233315FA80D0F563C388BC253 +2103F05E90DBF1923F229F980A2F4585C7A373511372D07DCBACA583099EA972C03E5AA67E663882 +6DB134564DB993CEEB6E7A6659C7C5C05C310267D5F8A24EEC2D5CC3E3F3C808E6D6068D1A57646B +37FABD98ECB7BAF99E7D9AC4414A491A73CA34C52F394352F6B5A15F0FC4D88622DAC694699C2464 +84ADAC3B1D366AFEDE2A2CD2042C90516A666A19A91C80248B11224BEDDF1A320E230739E755D098 +B6A67315535F4C187CFA67ED817A035056353FC859BF286317996FFFB478A2248B908FF12ABDE705 +402224A3EE5F463DD3D243875C84E02DB968ECA1CC52C75171EA50D6A88CA91327A7AA5795019F36 +C0A19C093A1C9D3723C7568F9D41F2E4FFB712FD47F897703D7A620B586B81936C84AAED61D84332 +B3BEBC4F95B796B93EF7A1F565C494F8A65EDB21E2EE18DC025522EF8E599887CA2836069CDDD889 +88E5862977B7472584303198CCE97EF9F9E1446D1F1F5ED1CFC666A8A0C3A03E1792EFB60A9B4065 +49E0DEDF6ACCDBD98742568B4735A747D8E5DE21E630125AE0C691D054E42199C15B1F80CAFA6E7B +B2005F374A9A5F9900ABB7409CCD50C3AFCCAB1214E6A856F7C7EBA89BC3291801E1343DA9DAD2C6 +ED075C8ECA1423B43E587AEC67E6145272814B3F191B3C285639F9E2D6E148A02DC2CBC0E054D629 +5CD05DBAC1950400A9189316F0265B86A732D302C5BEE8ED233768F237C62600CBAAFF3A110D5EFB +6CC7CA3B92D965CA7C5E8D3E64ECF239FE2507FC797FDBE54C1112B28D4DA44C60AB09D994C5BA78 +D663A2591934CC052BC70CD1DCA3325C66C9CB982E2039F5DB70C848D3DCEF655B1C2CD0CEC8865F +E8E1C0A267BE4F707ECE6F5A3DFCA3CC1EDF92C760439F51AA69A4C1801E96CA4D6EA4AD980258F3 +D15C893913ABCE09101984C61B91D603053E49A97CB82FBA707DAE8AF1D579FD69C8481CB7B712CB +CDDB4D287BE995E32C02B399602A08B9DD849039B5673F1930BEC7BF366EB082D2CA5DB2385C8CC4 +5BE3FC0E31820191A814EBA7C4F23B1938E6C4D800732787CD2CB97F762DFC85D4B798809B5F2254 +D826CA42B32695428D120298B44CF38494E56240B75DF1E41E46E53C44DC505452256DFEC819408D +605FF14D6C1F3F152F2FEA96EA0AB3B472D8704E06BE9F8C3E8395CAADD06D6DA033E81ADE5DC3B8 +3DAFF743C6E9E48716003D358DF63CD7FD3E2F727D1F2D0C29962F76D5C95ED44B6F08D052025A66 +5785F264A3D5F5593677B630E628B5EA81FB37CFFD7A30B7FAD226B6FDC82B0878AF4C0EC4F4243A +807B9839EA62BCBDF7C2E9B30A623876E632E084EBF4A21EDA04FC88A1C07021D0C72EC3E969D449 +FEB08E5826EC20E55B21EA71EA59F6E3B0710B0DDAB3261B4A2029ECAB68C19ADD5174E55D5E984A +4E5F38F592A302FEE6ECE732DDE841A28672C620CC5D687455A5C06FA9FE688394A04F96312ED025 +B7AA6FBCE2925F3AE559CC1886BEECDB70822E2E5CA3F732A87404B1536AAC469989E9610CFA440A +CE43875A70CA51F36CB6F629D9424C1E35A88F92D5DA3CD8CBAE6E8425A36968E21F4F30349749E0 +205BFF8D552837D6FC39532525370BBAC833F75F1854C93FC533A4AA53ADF7008173A70D94A4EBF5 +38EA9E62BCDA7C20E0A073BEE2EFAC34D2EF1D03BABD5147659E50B557045B2EB89DB303749B04D3 +F54B43FED612FCC68206E001A7AFE90230D9C12F74A32C7EDB5D0241DC3A5D51481FD7C8FAE08FEE +263FBCED7C7D911B3A303C835AF5FADFD218F61A9D6DE80485ABCA88200047B094441F7767B97A24 +E8C612590FA2407BAB1E8B56C71914EEF2355DD97CFAFCC192BC06FCE063D3D9D1A629AADC75E3BF +207234C208E7E30663EDD691043065C9CBC473D97C6D4DD3DFF59D6A9ABCDD4412C3128F603160AA +D8F81C6E7A4DCAF35F3A99B4EA10A34375B477C2BF846521A7EABD4D28078E9340452A198F3F5ACC +3DB7E3908939FF6E3709C6A3FD9889439A4AE3E10B618CC92E14B68429A3AD2C80940A1079452EC2 +66F254657BE7D79A2A24084AF73F6DF71FBCD32BF6913A3FAB25F977787F7BB0C3A3E8BAB38D7A2D +B0B4826950643DD1E03BD7DD1FB149A33862A89226B7CB454DAF613128C2075470E42E70A9444A8E +6ECA526345AB48E6F5160BA23B5BDDFDA6049EC44ED1461C7E0DD514B16E2FB285F72039DE3C7982 +EFD40D7F6C8E8F4CF35AC71B467BFC578002E8D2239A2FD2C4BCCDD8AF3D7DB1F4AE7F2D2E0811DF +9D0155BA6EDE50B5F052F14F6AB884FFF244D8806C07EBCB49ED22D85DF696995991A954AA97A1EC +D86ACD76E061B7541E87997FEF0657A826BD88EF3A4A5920462C6595E7A156F453291CA044CED810 +860C3B0149BCE73BECA713040664AD0591304106129600AF71317B0D2907839CEAC99515D357E980 +B1937B6E1200AACADA205421001F1B2F91753E80D2263C56AA164A74701A8D5FD28E46480B0DD963 +A683A1F355D7FB4463C7347C94EA5E2CA40B60B56297CB22D972C5BB10E56715A955605256C1541D +9F3BC5768A6F355CD3B863F0FA1A781EDB49368F51B29481CBB41D4AEB07AF9DBE8F52C5D0FF75F7 +FB6431D37D6AED84D78C778871CB0F715B4F07580F23B586C969C81B471FF6A6C7276F7E141E02A8 +584D4B9AB00E7BD643D2C3FAAA299B1F1E25048461952EA42D4882768A70DE46B213A287F8D31AC4 +6D5436F22A796C05D1FE50A9BC2A928066627A0D87DD57A3AD91DB446404B41557D1457873482005 +EA20916BBE46C613F456C849D46BA79D20627B446B2F49E3FA309AE14F8C420CFD94922CBC0FB9D3 +5A0F7DBEF577F1849A1A80E0011DA8AC082A8C6F61658E65AD177ABDF23EE17C8CF0D26B9FA3A6E9 +4837EB9E930336889767A8D7EA3CE980A8EA95528B004957BE6067CD9BD8E02A0F23CC1762CCA656 +D33412FF45E917FD4A03EB6E8C1F43FDB0A8965A33B4FD26BC24A20B304CA817E88495BA9B361A3E +933717FFB0271F7F70C5D3CBA1E86D0F51BF3ABA194DAF32C35C796627D00C7B2271ACE2463E37E9 +7B3C826CF3DB60028F240F9452CBE08F7EBCC5FDB1BCBB3C327A9F450B9E5671916101D6E3E5E458 +CA31F04D12F592F83BADA2C3683D3886AA3B403963AB5DBE220FEC00037A745839F67A3635DFD3BF +F08F367482962DED88ECF6322852D643A54D5D303EB04BFDDEE9BBA1EBCCBA7C653B3A613A8E719A +DEBE3CE1BD7E754E5F4977E863E3C2D388A65227B451D4F3A4F94E06513CBA4AC1F2F511613FF035 +611684CCC461599000E546E4D972CA6960E095A526E4735A23421A4C9B597ECE08AFA2753592BD16 +DED93255A1E33DEECE3C5EB77B94670E8137F2A4A4B98AC193258E7DEA5DB8408A806188F2D1DDC4 +40CCF0E9A6E2F0C78FDBD7B68DD4939D2458C1965BF8BED4564B32462FFF3EC892C03B11D3EA813F +AB4CFBE8D3016329C5B7E3DFED0F08284D44AA0B7A2F6BC96EA4503E8EF52A64C22BED6B452581AE +8FF8917D53976471941A9116A2D878FB2541B561767ABD4E31CCD8A590CA03494C62AFFD64EA0A1B +C779173DAD84999C7A8D844EB1259DE7BB5B25CD023537A474A524EBE4660B22568949E624D8FEA0 +AD37F4CE1EC75955EEFA49C6BF1803BE87E9C9865FF3F6B8525B8C15FE8835CA153D27E6C0FF0CA5 +1029A7A9185D25F0F14D86FC797DCC1F99EE97E2054B9C2A2E06FDBEB8DEF6CDD368BF23A858D9F8 +C1DEFDCEAF1B4A8DE5EAFC604CECCF0D285BE00AA912EAB66EFF4D37AD2EFE34853BBFD87CE09B18 +749B489943EECAE7887B006FB827D10191DAD18466CD1F86505879310A8B171F902EA0C26A388E13 +B53C700272CEE2BFB47ACB58247C13449C6BB9D01232C32517358F1A3DE064D43C18F8827D53789C +CF3CE2EBE78949A6ABFA1A6B8414CE360A5E22AFB7D1DCE6F5A06182C3B984B4F9BB1A905A9D5A14 +83750A1DE0A857CD5C06945EB7D4A2A6BF1237F32A154FDC06D51A703D44FE052FD3C53E9E8F417B +35D1C851F9203A8997521529F21AD8498F96930AA77EBAF82EE02A57BC77C792D9F220294B45F48E +A8FD94E01CD25645D36D168923562F3FDC93CB79DD4760DA0C103C2675722D7A1B79FCB4245ED12F +A0DB52492C9CCE58B333CFEE822812F7DCA68E802C451B5CFAEBAC608B950386B6C58239D1C62D62 +4DD5D15782FC552222CCA06DDF387B373E32C3C2864C63C768350C37283760F3515A5B0AFD66C48A +B522EB3E808C061F5CD6BD96CD18C9839D30508E7D4EDB88E8F11E31E10919B16B7971F06D7877A0 +58D8A4944C84FC6CAEDF3341B48B6E0D3C7B85D710E0C35F5B5053CF4B4798B3778CC28B2DC7AE0D +F3A49F9F3BCD8E95D746C35C3F47D68B8AA35D97AA08E711B5FBE70D1A623C82541EBDC51A827D0A +69E6C049087AD26F256EB7577F58CCFFBCCBA5A95D093DC29464C9A38DE95BC6B1853963B2DEB0B5 +7AD1248D6F1625E115EEB9510B5772AAE4E3C866657DB0B3BF0E0AC345E116F8D4976B770876FFE3 +748C36165522991F46A36F193DD1A1C94713673C7E4C81582391B636C72DE94CE6254374F99B623E +5686C13D8A8322E83E11BB0B0A896C6A8C2C4F756C5385CD7017F26D23F7C3EE97372C868C8C9155 +81723BB6B76B4C3CE8998E4FA6CA40B633DFDAA59BA902A4952DA90EC4FC3CF0F2676ACFA7F76F78 +236FA2DE10FD3545357215246BB7E527F277C28B353CC6D79DCEF21BCC8F77603CDD58A2CCDDBE3A +9802F941CED8E035313875319548C41992A2BE939A17CC109426E33825AE59BCD17CB19F50D972FF +CBE7D9B4B0BB095303D9DC9D406696C2508D6CE99E11CF00F6461147E97449ED5F486D480A86D3A7 +ACECB7E9A945984724EFC21C5079B1FD03ED803C2DEAFCE3327D2D7827715FD65D9506216C88B0FA +26935E95C64114A51919D419038B1A7E9C1E829FBFB53275093752DF19891A97F3CBF7719C1FD6CB +17019A6D2D25360ECA804C4B35172662CC4769D2B785C6C87E5A4ECCE31704E59F71263B7C3CAEC8 +ACB4C7426EC25F11A0042323EE6C3EEB04284DBAE2C770BC419DCE79BD4560AEA41571C3B595F525 +60191DC7A8FBF63D413A77A0905E517441B16C2B501EA2F9E99CC38D052679F288FDF1894542E3A6 +6989A0090185EB2E75134BFA3D9147C3DB8A621D9D35E37786853779E157B47F71626D6B3E633005 +9159C17596C1B87FE2B4FF47ED9D78FA4C2160077276C8B58CEF5DC030B4A5D83CF257096C047FE6 +4DE307C598B815058E72D5F57DF5C369E664E137DE29349E2F9DCD8C9F4EBA6E765B6327D7A20DFC +B20711273FD8091CBA605C4C494248076F7E03DF65A6A50164980BBBB708741E5BF6056E6F996DC0 +7FFF408C5B8EAB8DCEC315E92873228C805D4440A6470E3EE3983758DD211C9CECDBFAA4C9300CBA +00608A4B2404A3C7AF017A3B7E67F39F0B51ACF950D3E75CC7BC2B8D3480202FA958E8EE0B240501 +5232EE0D264C7CA02C18CA45CB3C2DE322D3EB7F00F9455DB6C5B1F4E59C3E95520EC36D7D903CBB +625D70B54BF6F8255E412604BBB29FEE026CC660577F91DB1DB4A613EEEFB20CF7AE3CD89D565AC8 +38416B01B5DE4FFA5550D17FB51FBBEBE21CF1D56038863EE931B90DEC2E211ED42BA92EC244D4CE +2C4EC5CA87A026992772DC2AF754FC982B94F36EA7B7BF75E0ECE90CBB2A6AA1A012E8898BD679C2 +3CB3827C35D5D02F0569C7AA82615D4AA67518ECF668D3B57D6EF1A8013424AC2268BA0D9A74D588 +79EDCF6382A89D397864940303EAEC45A38304BA8B1CB198967AE23EB81054BE74B16909A405E8A7 +799CEE3C270FE2A6DC50BD7370B6B2C8FDB9A87D88D5D40348D3984E39C693B6F4486D994778607A +80A3122872DD65E40492107C71C3CF708A9717E9EEFAFBDDC239C53AA9645B711038E59C8B861B37 +411AB2039BEDF9CFD00F08D9C5D76154427FF5DD39878CECC5D7BFB3F1F035087185C0981F3C2139 +BE84872FFAD3408531C4EA9387B89F5E3EC779E8850D50992DFDCF9132BC551E985943B07618AC10 +D1150451F0844C0DC41D6E17EB508DC8689EC726400D5A7F6FEB3CC7BCE05F09228B7CB2C5393664 +D8DD9A4B96B1020EF25D70AA2D91CAE93AFB5F2BF0AA18CA5C599FA1A708EF35BF8F7FFEC9AFC1F2 +42870D028B2B1459063B493943EF1283829783E1010242E5CF4DA39D93D506F3892936E7D6CF1124 +70A521D397438733D053944CFF12D6FFAE8246F20618684F263715AA98E15D72A526383E05C23214 +B78338E5B476F0981D90056E6E5D0DB66B1DF2298E597B2ABE1D817E18BEB056E65EDB4234342D96 +00470B1420C9210419D834E431B82F58608C87AC361A02D0F1FE4B470A3D71E0D21BB87E1023D428 +E23D596CB9E1A2184403A16E36E644BCCF9BBDE27290485057E62827283E7380AF786BF395B3961B +A5EA469C315763FA59E0F176EF81985F38B882DE56A74D128E256D1B89939728E55A92ABA21A6B78 +44FAC1BA7BBDD8B34A18194A2984B000380FE9F672E83EFDBF276FE797A325815B0F25CC95C97A9D +ACF56D583486305D7C9E51A7E337D14E3B900333EB38FD93A99587DA2341B10C059C71CE080FE753 +3C0F059FA40E560AF9C4A41A4BE6FB45846FF8F78165E10B4AD40F264BCF5596A1E8EF8CB6EA4B1A +3A5C69059AB1563843679ECB2511A90E8898F54295649CB73D277760D8D04ABACC7BCC6E777A0530 +E2067CCBC08673F9C8C178F9D672AC8A15E5367F0C5651B53E75E0CFA57C931746AE1A679C246D7C +9417F1CD89DDDBD1173C2F880B7B3847CBCCEBF99F7122E832D7C9BAFE2B54CBAA1ED48158DE3F36 +238B76B0E67644A28AEA996DDC006F6AC0242E4B667639E7523CBC90A0561193C1AF34481C2EF402 +EE43A82E1EBF4E3D601BB36B2D95CD93550D61CEE7A94E72F6D30C32C8F91A61E964B1F66ACFC398 +7F95D4028F116E9A9A8474AA29C1C1A984BE0E393BDC41DCEF6A6F1018DB60D52024899D8EB5D55D +324D73F39BFA47377B9E15B3B06A7585589FCF52A54684173E5183367E7B0952DC4BC2767C4C6247 +B1D6103E52BC7B7EA6298F454C5D97AC575F19C10ACDFF4E10C7D3755CFAB4200CAC545269FF1D8D +B0D607C7AD47F40DDF257AB4E7D0750577003C13E4941960C3DD7B0774DDAC18E8ABAF8F53E03CBE +F6D57B44F24CF821014C064278FD51B3427593D17694B4ABCE81F49CBB984C5878CDF0C38D1ED7FD +99B0B9A3BD8D8FF6219588B3B8FA59D0CDD1D9B2F65122AB45E48F1757467B9204926140E3C350C5 +A927A2E700173053EC35D3F1DA2D7258714C97FAA857F0898917BD94625C6D1E2D77138EFCAAAF51 +7B17FE187A2212C24A881A2C6A647DEF6376ED80AE4175C5EE80921F001995B44E49F0D33DD9075A +CF33BB03671C0BCC34AD5784AD1CDFED3A6D9BA103B3DDC1CC2DE74DBB576A0277715275218CD19C +A8899209125266D8BF1286F881DCC2C383749D1E768D670F4099F7DE959EDFE852583183C9111601 +2881A56A24AAF020EA45CD5F39660DEBCE30AC1C7B8CFC60387B1B0C3E361BE612FDFA9F01B7E4B4 +A18839A2C7E0E393EBC5AD9A8A4EBC316A740C1C295D9EF5F4DFFA0667F9582C0BB837B142C4CFC6 +B1798E9476D0631111033B8BA75A10FDC800E2AB1E0E829632F869CFE4737BE9E2800759EE0831DC +7D1195EAF80555771981DD6DC6606812D92CB8EF86447F5F6C6F626D0E265C67E52A6319189EE349 +D48E49DFE6A9E98F76C414A1E3217AE0A215A17E54AA498F4ECDC50242ACC7E2322F63BB2FF2189D +057E7354E32A3ED1803116176B9B9D0129930F919E2FEC280B2C8924E49E7BB75768A2EE1DA8ADBE +D4E3589906DF1B923AEF84C1BD327438B731012E69BB0D43A1842CB88BB54EA4516477F704CFEB28 +6E3EA483445AD4D74586FCF32E96D366901084365F693A53C5FB532FBFE7BC0CADC404C4985042D6 +8DBB90A6DCDA3531EE324D558A214F935CD9FCC9A0CEBE9B5FB0323F4B3820529599EF48EE068B5A +CE85004FEA2984F0A86F5AC9D56163BBFE1142B774148F1EB0A4DC89C3349052533A7DE66729DB24 +41B82F8F7360111DACF69293C9B281A0534F3E9E9224A75C49A832F28B2E497262475507B6DDFA9F +01CA0A6696E3F5AC7EA68595EBA0C2EB8A47813FF936D84AC1B23ECA7AA2862B793CCBB0DF9FDD49 +31BEF354CEC12FBF478559FEC29F81ADF4452E83963E56541D31F3691C93A50F0BBA5E9552C4F2A2 +3A6E53060729854A3DD71CC4308B91957DB19E66AAA18FA67055A950F1C2CFF78A03BC1A588CF624 +696068068719AFB1001C4581EE072113882D9052B21E355D401ED8CD24D067B99E616BDA5A0A5A93 +36FC499632B79FF2FD0DEFB096EF46B75E2D4E0F48DAEA239719FEC4D9A29818F5875FC5041A9EDB +D26CAF0ACE14CC80BA49BBA59E918EB3D8F1E541AA16026585A2F72DF7D83541816DE46981FB3EFD +0C30E458CFAD04C79421AB7C4925E23AEA07F9F018431C790002596D26BD9663B51B699DF53E4882 +CBC34EDE88EB55045B889B6062E35FD1E018BCE785157B85EC3B9CA6C85D4B16238275385B8285DB +012D8FB7C9F5B946A41D7A0FB878FF72C39683144D8A007CFF631B43748F2D5FC690300F9BC0C837 +006B92ECEBE0605E8C3A4A400E18AE8997D1B45FEE10068E247C647CF82C6DFBE5E881D511FFA687 +B7AEB78546BFD07D5F7EC242DCEF4930D8AAAD8C6152B6642AAC325963FD147F236BB850A9966573 +9D06CDBD7CA79A527DCF461E33F22BC9C5DB00DA2BD3DDDD8C99D99793BC98282AA8872FF96C3942 +85D82D9419EB78B6AE37A5F519397700F75D624A09BD255B576E955A323E784E8FC31131F003B0E3 +024A4F58FEF2A6C043796201FC425482E1155E229D1B2D43EF7B0D22322B22EF5C9A1BE026A1C3D3 +75EDAFF99597E1E5477952A4E8D2ACF5D014BC00DC2A272FA62B6983E27D228881E2EF2B8B95A681 +CBE90C5FDE16331C85222FE2A16F0A3C3000A63E2E21666C0C119F8AF89A543D37977069A5ACF155 +6324F05204CE8CAD50FF4FB630D9CBBFC324DEDA584AA56A99D3A76FF55BDC2C2EA3A021361CCD4A +83C7A5E2768D210FA6DE889FD48A39D679C94EC3C99A8D33FF11377DA7F6F1B71A2A05B302ECDE95 +4F26773F39AC881542F0D0969C3995C3519A8EF70B4220D86BF01BEECC6462855E7B686E1AFF1CA9 +1FB8FD8B4A69E10EE0C2AD94ADD44449506F9B6EF43641F2026EFF6E605C670560C2B74706FB949A +A7E8CC6A2D0D6207E457E7FD87EC1B9092DC68B9143947CC8ED14AFDDCBF8FDDA228A76847F96802 +E561F67CEEFDE45AE587673983FC04C96744DBAA83F2DC838D633943C75DCB9E6410474EB27B348F +26E505F0AB90878940E846C5E9F3C5FE8C3558C3236B1B88C405716949B8506841CABE1717474BB7 +C30DB91CDEE33B0F844811762FAEC535BDCF84C1C747CEF9B1FA61D2AFB5A81335BC42C06A94D7D5 +9B7EDE55BCF6F9867AEE107555CDD084B7684C2C87087475A39A9DA6347BE281CE5635A4D07865BA +98CE26C1465B1AB0343F49FF37B4D0CA9F3BB693D78DC3B21925CB996A038DCC172527FE57C07460 +EF39C07D4396E7FA970D9F22ABD21A9C794B64AD96762C7428F59A8757C36D6C4FFB23216195A04C +2A2C2E7B10EF7193931544D782FEE4B91E01119C5553BBC6252270A8D8C56DD62D448F5AD8DC69CC +B45E1F17F0AA1E445129DD00F000005B23D38DE93A3BE55A4C041947F36B4E4536E307D0180553F9 +2E46B743881CB5D5386C48C7D5F84C2BCD06B9C501F78C7EE61FA23516791FCF4DB278AF688A2E60 +10A56692AD92008497487EDFE4BD5FA083FA544138B20D6940020887E35D46E093B71F7A04A67460 +DC8116B4D4839625D7CA6959D6831CD93F81AC4EA2709036DD738364FDE71113BF22EBF13DFE1642 +E564701E6F0FFE7511EDF03FE448C2B28C64FB7D54B94CA576E481FA56B2B18AF10C71F699B6BFD4 +7459CDE1869D0FD306BF489A6F42E5B2F05CCF55BB6B9526973D19CB134CA7F13F1DB3716F8CC217 +73A832568C16250B5CDB16DF24BF81D49F5B37018BD310262EA7078107868AB0216CEC83CEFCAB1E +9F2C665A31585CA04DC01879CAA79AAA5AB201B516F7052B01B16BEE5606098393B0E5D9F9E5E3F4 +EB20F63C958E796DF41CF28839F5C62A0431648745D7837B519F3AA36BC6C08EF040CCF53D9B6D8C +0C7D1A84D707EC57A3C6AC9A62AB37251A01A5ED40FDEC6F5BE6E34C6A91D058319439778A2EE5D0 +363E2E1F33463C33327D05FFC0CBF08D5BC457C7230448972FB9B4D0D782BA7DBF10D3FFEF8BF523 +6EC16D4DD6D0D870D9D5EB5C64C9A46A4F583D4F831FEE74B0E5B33A09ABFD4444929BD8F638CD72 +EAB99CF2E9551DF427683964A592E49D186F285258C5D5F62196A98532421D73E3495F82695FEEC6 +E1952C562D546B28618FFAEEBEFF03A57F4D855021F85B0C7BC37FCC6DA9AECA099B646B99D41896 +09D3FF2D56422F8C37E97640293EC7C90E3380887836F4938FBF495CAC14FBA5648D89282D8D49D9 +1AF73ED36581139D8BD42551E263E830EA3C6EB381D85C42D74C50DB0CCAEC03F535ADE92128A016 +0E811C34748309AF7604919B66CD43EB5CA975302DCB6076FEB6BDD6FF55976FE990FB0CE9ABB11B +195403FB26E3D6C6A0DE1C5BE79E171A61E21F79EE8DBE7A832519813EF6B33EA098C2C32ADEA219 +AB2AAC8B093F40000995539D1276D5F2EF84CCD099B71FE4269BDBDB6A8D59C86F7D2E3FBCCF8773 +D0FAE97640BC1AD43CB4B992BFADFB09DBD0CAAEB8CD9DA264187C4F97300E9A6C9DEED5525479E6 +05C65AE336CBBDF4E5D7F79AD098F977285E065579B748FEAA97F2A753E1F962FCAB68D72BAA8EE4 +FF6691C23E31BC0F3E981A96FB440404856AE1AB32A7205B17D411D8F21C8C93B704D07EC594422A +BC368CDA2B1610CE6A973F4474E12B78B532666797F5755D269772C9F5400B3BFC6C58395D38527E +2CCCF29B56123F7DCEF3BDE5DC1DFC5B0293BB125085B1D2D929BC3EE84F4FAD571A4991C3DEE03F +2DB3A3097E52B1A7D5C73CCB6148EAC62E8E36DE9A71C57638C6E4D5D9DED18174E8C390E50B4A5B +913C074EEAEBE390B214B3A68F02862B9A296DB4B409769649E51D738CBBDFB7702E15C73C2AFC6B +C37CE15171F4E822CF20EFE55D9F061AA43E648989628FF79E65932390CBB15D8E621333B18B11C3 +BDF96F841D7434E01AD501FEA964A75B248A35CD9DF9A37E48A1E5A09C624B93CE44F0042FA00D7F +9EE89B9F7AB785E9C718CF6E7228F743271C2C9BBA17E5208B920E44E765D99D86650EB454B0FAAA +112753AA1BD3A24239E9C5FC47EEB1547AC9D23731B8DC48B9707830DAEC60C8D3790BBA1120F776 +4EFAC542CFFBCD5C05F9510B27B2534B704ECD36C8B041FD49A96881302FFF5B0163A2DD09C751D6 +D6AFEA9170A4F4C4AB8D46E62F763FE1BDA51DD1CE4A27E772F3A2869155F762FF26B7AA6FCFA4F1 +292E56F03AAB6322BF867E7710C34D43B5D85B45AA68014AD7879EED051B1933E491496E3E26D9AA +8B80A07BF2B94F1077E84A9726F08199887D66DE7A307BF33C30DD9CF3DA188088C03B2BAD09A217 +6B110DB2C868B53DA9A66C85737BA66C93C58A259860E294AD0191E3A72C73F40B0BD98699AA08DA +F03587B78F391F3A4313C58D9F29B53C70785637BD0C58310109C54091AB0A34CBB0C478613A7AC0 +FB8F0A8B4645AC966395D8BA775262CD291136AFFDDF01C1D83DD4EB3B59CCAD18057FE7D92A8CD4 +A58F22508D9FD7CF356571F701BBB23E749BDDCBF8A317FDA0AEFD952BB18545610FFAD3AC143D35 +1B8DB3F66293375E0E50235F0D0466932181D377EDD32A5F0FFA4E22B5A0CB4F343D9A7E4A342E9D +09DFF6C697630CD3971802C277A5590B8CA94BDE6B38446C794D072BBCCB724D5BC208EEF1B018D7 +39373BB910D668882CAA779C2D686081DE6A2606417B54D7C20E0E7F722648D893E4EDBAE8F00D6A +6DA3712F91AE860C756D1127D133AB828E9D80023B50B162C5A1C5CDF70CCB3FDD7EA060ED20838B +E1E50C4094C9E79E1A0187CDF780CAF45A725964F004253E034C5BE46BBF89D94631F1A33BAA35B8 +4FA2A9D08481C6674126CD96ED05DCE48BDA069D902D6836D5DFBA701DC0F98A863E64F0E312145D +8DC0B77F25B43AEC729A1243B45B08CA228DD6101CAA2AC5ADCC8EFF84A4CA3F254176C2CC711EE6 +C273835D0FD3528ECA2A976B88E51FE347FDB60F32370B66D338931D6581630ED586F349C638960C +31AE4204E89521A96E1219E696B913DEB2AAB7A3B022D06F34FDFCB810A04E60A4FEBE284C2F063E +0AE9EDF87704921CCFA193BDC912B747E13570066223A49F1F6E2AF0D4D65DA04CA876FF7A462FFC +9C0BA2CC545C3BD36DBE762F32B2D6BE5867C59F479195C92440DC165098B74EA5C3AD93CDF2D410 +B04C16BC7801E7956F4E5107450787AA592493171C3628E6B8F49D4F8429EB98DC52EF025F001387 +BC1A7093F7A99F10B5D2D7DD8BBB393BF6E56F08F4F7FA1A343F220D5A1EAE7168C74D41BE1DC1A8 +3BD65B72B982F4F7B34F24F97F9EC9A91011064031FACFF2A14921A32024385F4E061CD07D152E74 +1BF97156D951A342488FA7F5EF934CCAD13E2753A0AB7A1F565C2F7F6B349DF03BBC25BBD972A9AD +F809BB5C5048A8CCEF9297B2ED3324D18867F293CC66E88B3A39D107B610DFE79A3B4E83A96D3D52 +A17FE8A62C9FDD271130148366942C9CE57558D023DA5F7501319EBFA33DE9E6D1E76D7C20DB8A09 +B657839DA99F3D8143F1EE6253A3295C9651FA4366547893C2DC7ABCBF4BB7609DE5D001E0A36D9F +FBE01F7D0903B3208AE8547E2E5F14EC1AF4C2535CA8F4EA37E3F3CE172C7A1E8308995B1CC23E6E +81190246BCAB6E755BF868D449BB02A2AA87C44C9CC0F571ADC72547CEECBE104BB274B8AC16DCB7 +5D5F458D356466B921ACDEEAE384E2EB1DF6EF393B41B9747F0A4FAEB4AF1928D9AD6FB7E06FDC62 +1E4C6FC98CFB43F88584BD55D9B97CC9549093EDE586912161931162B1B1D52D0443260DABA02AF2 +B4432100D5506546013DA703573FA8013685CC798CE501960093DED713FFCCF89CA2B9106390198C +29A00864108CDCC1984A8BAB53919028C01B26ECC7925E38CBE6CCA8978EE21C2B06E7B3E48FBA97 +8E2A7D186E563C088F84AA23178B60E4729EE87D67B1091F3B6973676C1CBFE6530EB773C62E2C24 +97014AB0E8B71A1F4E86A378AA26591511BEE3CF3D64C94848582E1354E1605B6457823F2C5E640A +D3802946BB2E7E8E594E8C04B430C2385DD40746CE8534F50842E74D7115F3DB0C72D1C9C607C657 +3B094AEB73B7A79876CFFC3E2F8C9FEAAA07D3BFCE05B61F7749A8793BE90CCCECA2D7077F25E899 +D3331FE161A7E86C842495D584C6E4A0880B2951D8A13B88C4672080A0B1BE36BF47C3ACE7288CFE +41A8C1BAA6F0814A947FBD6B3AA72B6C73A8C578CA51CCC96F2352316C467BB960E981F2B6485BFB +44B577E71EFDA16E7405954BC7C9F0759F5A9F1EBCD2FA9CC9648D5831A68887F41B15081A204C24 +B4B992A231DEF9E698D4C3A25B6F5474F5BE6A601F2D337A58A0D21FF37FD91EB86D1D738893A03A +69F0CD743F611CDFFE69DB2C6ED0E4611D56F803BB0DC06E7FE85A303839612707647B1BE9FAF8D6 +84122CA9E5CB8BDE2936D3F4FF254D31529D7538BBD4D35539489F9E7316F24214B996BCDCF1818E +749A71CF0E8845AA1E2A58AA62A48E02BA4564625D20AA220EE719608521D7D7A7FCA0BD8904A401 +9819D371F3F59D46C1354E5FC1A6E5F79B20CF4ACA2BF0F2DE73DA193A6F9ACBFE0B4731C4BCEBE6 +D96FE822965DE965232282A3A130361F188B3AABDA95A8A2790D9240BE008B6A6DE4BBFCADA05B67 +86B9BB8E0DFA0C30043A3B07ED46277E07B9808422C8ED16758B9C396F4EA929D769785B2C9568E5 +70A83B989B25CE200F1727D41E2B702E7F88F1784F4C83FA60A74EB26B2DA95126E508ED519A61CC +151DB6804F61826C5F86D8FA89D06E526FED97A0DB88EDB432FF32C1ACC9B622EEDF601081AF7B96 +3C9CFC1D13E4A9C74FEA0A1C8E3D8653CD92A944D4CA6B0D306619AFD503506D77732D6514F604BE +4610C2560931BDE0B40939BC1D126B0E97F72AE1B4A9252123B54F7A27E0CFA4425B4546526FD741 +CA77952B10D13E0AC2E32006A903808FF0CD013F936238C74CC75FD915244C56A8412F37F0134840 +347699508D6F3D7F3203A25B7C70100719582CD588590EE34B3AB13E255B613A6D00386A0104CC5E +D2C646F09A88888D3751651D5646C5227A3C80E8DA1B0A331121DD2429F1F4775D30564DFF47D01B +BE2C6C72CE4D1FD9A2077C04D2B0274B8916F6A9D1A4A6964A534F47CF241D5A8E34B23F85BE9ACF +FC2FEA961F277539F215F8728D6788F67BEAF45502839BCF23D8763C3949352F00C579A9A4FC408E +C625E310DAE61512DFE6844E82D36A2F81709E1F05B38AE9C222ED62C961EE63593CED7AAF73CE2E +D3667740C77B309B93EEFE1B4BA65D48575A66BE86743DC9E5D3C2FF418D11F7F211B86E827EE1DF +C3613E7498030F07050524536D1F8A94DDB6698BE7B963C55CB3F74B676CD815A7B3DF4B1A0EA2BE +1B0B9A11FFBFD5B1FA49668AEE14629316AF436A0821C20BEEF7B3480847934A99F6D85B68F4DDF8 +859A754E009428AF89A90D1852C220A607FF0806E8080726EDC94D691D214B4521C147C4273AEBDD +BB4A697EF16448CD9B2FC95293305858DECFD406B89B9F3FDAE2AC579E80CF321EBAE5701FB2F7CA +D8ED04B4A63115886D45D6120F69AEF1A21D80AD3C2D35D2899F1902242B96CD349E0AAADA40F7A1 +1282B6B52BDD97708E58DC5E2D22D1153E5FA3F3B300BCDFAF98DEC2F4E3C82A1C85F985735F3987 +4F557579F422664E07CBE19DA680EFB0FC82C323EC5C4644C51709AC8D674608A8043C91E6C7988D +430F10BA6CE1FC7FC0604FCD8F723895250AEC36CC35B3FA14FE2A0D24095DCC30B2093F2298F5F0 +A97676A0BE66C3DC9ADACFE2FC0F721A20E945AFC1096A619075D5E9A264C796EC6C90EF1AEEA8DC +089B44FFC13D27CB2370070A52D4416C53F364393E46EDD7EDE00799960CE6E0D57E4909E88ADD64 +BDD2B0EBE2D73FA6ACF8B40280DAA0637E705C65AABD523B8815F22F23E9FF81E7829C7E4BC980C9 +143AEBE1A04DC0D253396BBB7268BD5AEEA356B610D5DCEE03135E00AE34388251F31714A1C40E18 +2652C48CDA2211A22CB6F02490E69A44CECB169754C53B16028D352E0119F5D5FAE0BD7EA1CDA647 +12A6147374B64244E21E9EC9F0D1381AD22D5B6212B26C3F9AA5F6045F25DD9F5EB4489EA39B1945 +331AC70510C5752557DE21D0A6CFC1EB10A98FA867B76DA6E4249469F591FD154D39E89364A43DB0 +07AA0D7A911CFAE6CE2B557997FBC44F55A27F622BD7B8B10EC9F5D10F2649A646FD964AE1B111B3 +5B46A252C4DEE44E7426EB5739F24E8A390694597DB3A1FE7800C97E59558322F0E49A0CCE2AD94B +1E2D1026AFA771723E3F523916F55ED866C9FB4A2F759651C613A2CFF362028CDF9D38F05D4C7C60 +24C533E930B64B099FB1AF04B01F5FB9CA6867E6EFF55A772C5391831059987E10CBF987E3F378E0 +1329F73D54DC0484177D3C3C06F67397955FF1CA4EF8AD1606B70455255D631A7D6EB92BFDBA14A0 +FF28B2ACE7E81AD666EA9B3A0F5A6BA3B5DFE35044FA4B3D8ED956009C60E98CC132F2E84967F4A9 +8A67B336D5EE7CAF7DD1F74D1FA08619941361FA7312CF225D89CEF97E864C8369EAFAB94D97F056 +5505D825972B754F6729596EEA91210B75DD8F645382ACE36DE60819A02B3B48DD00F5485F9264F9 +FA926D732E2C267B0BE8CA98526F124F97EFDB86132C5EF16B103908172FC51F286FFE45FF253512 +E0033F037FF182BA536A9EB2DF2D1DB257D9C86C46E1B002FB32AC70CA9462E6EB48994752CEBCE3 +9F08ABD4F4B0889283E55500702185A841E328 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndResource +/NimbusMonL-Regu-iso1252 /NimbusMonL-Regu ISO1252Encoding psp_definefont +/Times-Roman-iso1252 /Times-Roman ISO1252Encoding psp_definefont +/Times-Italic-iso1252 /Times-Italic ISO1252Encoding psp_definefont +294 254 moveto +0 0 0 setrgbcolor +/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont +<202020202020> +show +445 254 moveto +<63617365204D45445F544554524134> +show +823 254 moveto +<20> +show +848 254 moveto +<3A207B> +show +294 298 moveto +<202020202020202069662028696E75656C6529207B> +show +294 342 moveto +<20202020202020202020666F7220286A3D303B6A> +show +798 342 moveto +<3C6E6D61696C6C65735B695D3B6A2B2B29207B> +show +294 386 moveto +<202020202020202020202020656C656D5F69643D2A286E756D656C652B6A293B> +show +294 430 moveto +<2020202020202020202020206F6B203D206D794D657368> +show +873 430 moveto +<2D> +show +898 430 moveto +<3E416464566F6C756D65576974684944282A28636F6E6E65637469766974652B6A2A287461696C +6C6529292C> +show +294 474 moveto +<202020202020202020202020202020202020202020202020202020202020202020202020202020 +20202A28636F6E6E65637469766974652B6A2A287461696C6C65292B31292C> +show +294 518 moveto +<202020202020202020202020202020202020202020202020202020202020202020202020202020 +20202A28636F6E6E65637469766974652B6A2A287461696C6C65292B32292C> +show +294 562 moveto +<202020202020202020202020202020202020202020202020202020202020202020202020202020 +20202A28636F6E6E65637469766974652B6A2A287461696C6C65292B33292C> +show +294 606 moveto +<202020202020202020202020202020202020202020202020202020202020202020202020202020 +2020656C656D5F6964293B> +show +294 650 moveto +<202020202020202020207D> +show +294 694 moveto +<2020202020202020> +show +495 694 moveto +<7D> +show +294 738 moveto +<2020202020202020656C7365207B> +show +294 782 moveto +<20202020202020202020666F7220286A3D303B6A> +show +798 782 moveto +<3C6E6D61696C6C65735B695D3B6A2B2B29207B> +show +294 826 moveto +<202020202020202020202020> +show +596 826 moveto +<636D70743B> +show +294 870 moveto +<202020202020202020202020> +show +596 870 moveto +<6F6B203D206D794D657368> +show +874 870 moveto +<2D> +show +899 870 moveto +<3E416464566F6C756D65576974684944282A28636F6E6E65637469766974652B6A2A287461696C +6C6529292C> +show +294 914 moveto +<202020202020202020202020202020202020202020202020202020202020202020202020202020 +2020> +show +1327 914 moveto +<2A28636F6E6E65637469766974652B6A2A287461696C6C65292B31292C> +show +294 958 moveto +<202020202020202020202020202020202020202020202020202020202020202020202020202020 +20202A28636F6E6E65637469766974652B6A2A287461696C6C65292B32292C> +show +294 1002 moveto +<202020202020202020202020202020202020202020202020202020202020202020202020202020 +20202A28636F6E6E65637469766974652B6A2A287461696C6C65292B33292C> +show +294 1046 moveto +<202020202020202020202020202020202020202020202020202020202020202020202020202020 +2020636D7074293B> +show +294 1090 moveto +<20202020202020207D> +show +294 1134 moveto +<2020202020202020627265616B3B> +show +294 1178 moveto +<2020202020207D> +show +220 1289 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<4D6F64696669636174696F6E> +show +507 1289 moveto +<6475> +show +583 1289 moveto +<66696368696572> +show +740 1289 moveto +1 0 0 setrgbcolor +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<534D4553485F5352432F7372632F4472697665724D45442F4472697665724D45445F525F534D45 +534844535F4D6573682E637878> +show +220 1344 moveto +0 0 0 setrgbcolor +<706F7572206C61206C65637475726520E02074726176657273206C6520647269766572204D4544 +20737572206C612073747275637475726520646520646F6E6EE965206475206D61696C6C61676520 +534D45534844532E> +show +294 1445 moveto +/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont +<202020202020> +show +445 1445 moveto +<63617365204D45445F544554524134> +show +823 1445 moveto +<20> +show +848 1445 moveto +<3A207B> +show +294 1489 moveto +<202020202020202069662028696E75656C6529207B> +show +294 1533 moveto +<20202020202020202020666F7220286A3D303B6A> +show +798 1533 moveto +<3C6E6D61696C6C65735B695D3B6A2B2B29207B> +show +294 1577 moveto +<202020202020202020202020> +show +596 1577 moveto +<656C656D5F69643D2A286E756D656C652B6A293B> +show +294 1621 moveto +<2020202020202020202020206F6B203D206D79534D45534844534D657368> +show +1050 1621 moveto +<2D> +show +1075 1621 moveto +<3E416464566F6C756D6557697468494428> +show +294 1665 moveto +<20202020202020202020202020202020202020202020202020202020202020202A28636F6E6E65 +637469766974652B6A2A287461696C6C652D6E73757029292C> +show +294 1709 moveto +<20202020202020202020202020202020202020202020202020202020202020202A28636F6E6E65 +637469766974652B6A2A287461696C6C652D6E737570292B31292C> +show +294 1753 moveto +<20202020202020202020202020202020202020202020202020202020202020202A28636F6E6E65 +637469766974652B6A2A287461696C6C652D6E737570292B32292C> +show +294 1797 moveto +<20202020202020202020202020202020202020202020202020202020202020202A28636F6E6E65 +637469766974652B6A2A287461696C6C652D6E737570292B33292C> +show +294 1841 moveto +<2020202020202020202020202020202020202020202020202020202020202020> +show +1100 1841 moveto +<656C656D5F6964293B> +show +294 1885 moveto +<202020202020202020207D> +show +294 1929 moveto +<20202020202020207D> +show +294 1973 moveto +<2020202020202020656C7365207B> +show +294 2016 moveto +<20202020202020202020666F7220286A3D303B6A> +show +798 2016 moveto +<3C6E6D61696C6C65735B695D3B6A2B2B29207B> +show +294 2060 moveto +<202020202020202020202020636D70743B> +show +294 2104 moveto +<2020202020202020202020206F6B203D206D79534D45534844534D657368> +show +1050 2104 moveto +<2D> +show +1075 2104 moveto +<3E416464566F6C756D6557697468494428> +show +294 2148 moveto +<20202020202020202020202020202020202020202020202020202020202020202A28636F6E6E65 +637469766974652B6A2A287461696C6C6529292C> +show +294 2192 moveto +<20202020202020202020202020202020202020202020202020202020202020202A28636F6E6E65 +637469766974652B6A2A287461696C6C65292B31292C> +show +294 2236 moveto +<20202020202020202020202020202020202020202020202020202020202020202A28636F6E6E65 +637469766974652B6A2A287461696C6C65292B32292C> +show +294 2280 moveto +<20202020202020202020202020202020202020202020202020202020202020202A28636F6E6E65 +637469766974652B6A2A287461696C6C65292B33292C> +show +294 2324 moveto +<2020202020202020202020202020202020202020202020202020202020202020636D7074293B> +show +294 2368 moveto +<20202020202020207D> +show +294 2412 moveto +<2020202020202020627265616B3B> +show +294 2456 moveto +<2020202020207D> +show +295 2573 moveto +/Symbol findfont 50 -50 matrix scale makefont setfont + +show +370 2573 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<4D6F64696669636174696F6E> +show +656 2573 moveto +<6475> +show +733 2573 moveto +<66696368696572> +show +889 2573 moveto +1 0 0 setrgbcolor +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<534D4553485F535243> +show +1161 2573 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<2F> +show +1174 2573 moveto +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<737263> +show +1235 2573 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<2F> +show +1248 2573 moveto +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<534D4553485F53574947> +show +1550 2573 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<2F> +show +1563 2573 moveto +/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont +<4D616B6566696C652E696E2C> +show +1826 2573 moveto +0 0 0 setrgbcolor +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<706F7572> +show +1943 2573 moveto +<6578706F72746572> +show +370 2633 moveto +<6C6573> +show +465 2633 moveto +<73637269707473> +show +635 2633 moveto +<707974686F6E> +show +813 2633 moveto +<6465> +show +900 2633 moveto +<7465737465> +show +1031 2633 moveto +<6475> +show +1119 2633 moveto +<6D61696C6C657572> +show +1326 2633 moveto +<74E974726168E9647269717565> +show +1589 2633 moveto +<20> +show +1601 2633 moveto +<3A> +show +1654 2633 moveto +<534D4553485F626F785F74657472612E70792C> +show +370 2689 moveto +<534D4553485F626F78325F74657472612E70792C20534D4553485F626F78335F74657472612E70 +792C20534D4553485F6D656368616E69635F74657472612E70792C> +show +370 2745 moveto +<534D4553485F6669786174696F6E5F74657472612E7079> +show +912 2745 moveto +<6574> +show +966 2745 moveto +<534D4553485F506172746974696F6E315F74657472612E70792E> +show +1581 2745 moveto +<534D4553485F6669786174696F6E5F686578612E7079> +show +370 2801 moveto +<657374> +show +468 2801 moveto +<756E> +show +560 2801 moveto +<6175747265> +show +703 2801 moveto +<736372697074> +show +856 2801 moveto +<707974686F6E> +show +1038 2801 moveto +<6465> +show +1127 2801 moveto +<7465737465> +show +1261 2801 moveto +<6475> +show +1354 2801 moveto +<6D61696C6C657572> +show +1563 2801 moveto +<6865786168E9647269717565> +show +1875 2801 moveto +<74616E646973> +show +2037 2801 moveto +<717565> +show +370 2858 moveto +<534D4553485F666C696768745F736B696E2E7079> +show +859 2858 moveto +<657374> +show +933 2858 moveto +<756E> +show +1001 2858 moveto +<6175747265> +show +1120 2858 moveto +<736372697074> +show +1249 2858 moveto +<707974686F6E> +show +1406 2858 moveto +<6465> +show +1472 2858 moveto +<7465737465> +show +1582 2858 moveto +<6475> +show +1650 2858 moveto +<6D61696C6C657572> +show +1835 2858 moveto +<73757266616369717565> +show +2061 2858 moveto +<656E> +show +370 2914 moveto +<747269616E676C65> +show +621 2914 moveto +<7574696C6973616E74> +show +880 2914 moveto +<4D45464953544F5F3244> +show +1279 2914 moveto +<61766563> +show +1469 2914 moveto +<6C276879706F7468E87365> +show +1792 2914 moveto +<6465> +show +1938 2914 moveto +<6D61696C6C616765> +show +370 2970 moveto +<534D4553485F4C656E67746846726F6D45646765732E> +show +1028 2970 moveto +<4427617574726573> +show +1275 2970 moveto +<6669636869657273> +show +1508 2970 moveto +<6465> +show +1637 2970 moveto +<7465737465> +show +1811 2970 moveto +<736F6E74> +show +1977 2970 moveto +<7072E9767573> +show +370 3026 moveto +<534D4553485F506172746974696F6E5B322C332C342C355D2E7079> +show +1000 3026 moveto +<6D616973> +show +1110 3026 moveto +<636575782D6369> +show +1273 3026 moveto +<6EE9636573736974656E74> +show +1509 3026 moveto +<756E> +show +1576 3026 moveto +<616A757374656D656E74> +show +1809 3026 moveto +<646573> +show +1891 3026 moveto +<706172616DE874726573> +show +370 3082 moveto +<6465206D61696C6C6167652E> +show +280 221 1 967 rectfill +2125 221 1 967 rectfill +280 221 1846 1 rectfill +280 1187 1846 1 rectfill +280 1411 1 1056 rectfill +2125 1411 1 1056 rectfill +280 1411 1846 1 rectfill +280 2466 1846 1 rectfill +showpage +grestore grestore +%%PageTrailer + +%%Page: 6 6 +%%PageBoundingBox: 18 18 577 824 +%%BeginSetup +% +%%EndSetup +%%BeginPageSetup +% +gsave +[0.24 0 0 -0.24 18 824] concat +gsave +%%EndPageSetup +%%BeginResource: font NimbusMonL-Regu +%!PS-AdobeFont-1.0: NimbusMonL-Regu 1.05 +%%CreationDate: Wed Dec 22 1999 +% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development +% (URW)++,Copyright 1999 by (URW)++ Design & Development +% See the file PUBLIC (Aladdin Free Public License) for license conditions. +% As a special exception, permission is granted to include this font +% program in a Postscript or PDF file that consists of a document that +% contains text to be displayed or printed using this font, regardless +% of the conditions or license applying to the document itself. +12 dict begin +/FontInfo 10 dict dup begin +/version (1.05) readonly def +/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def +/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def +/FullName (Nimbus Mono L Regular) readonly def +/FamilyName (Nimbus Mono L) readonly def +/Weight (Regular) readonly def +/ItalicAngle 0.0 def +/isFixedPitch false def +/UnderlinePosition -100 def +/UnderlineThickness 50 def +end readonly def +/FontName /NimbusMonL-Regu def +/PaintType 0 def +/WMode 0 def +/FontBBox {-12 -237 650 811} readonly def +/FontType 1 def +/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def +/Encoding StandardEncoding def +/UniqueID 5020945 def +currentdict end +currentfile eexec +E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89 +699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641 +2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2 +5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF +9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A2261C63C769D2F4B60FA2C438AD7D199D8E4 +5F7E7C9A605C8CA14E21FCD81C9A515FB8DB6F99604534D06EA9D87FE0FAA852899C9D0595C7A97E +6C55F79FAC45CD38E87B10D210CE7501E88C8FCD3444354365FB893A12F596AE2C1E70D5819EE0D0 +87D10BF8DA96F3DABD5405D28C4228C6C31BA4052464859640933FEEFD8071C0C84CDD829A9B1D0B +A01F25A4D50EE2EA2B45160CA6333B2D2800306ED2BEFDFE155E9D9F9342EB8D5B0ADBF2460CCC98 +643FB1287CCD28ABA7B5CAB92EC39EE2E918990372B16F8487EBA30EAE88708B6CF33B6C015D8096 +C7CFE2F139F52052E3925C0D50FD64CE68236D59CB83EF56BFC584150EC38065059F3308AD6F9A99 +F83EF4E6CB13855C8175E31417D190D036B387D3952344A950F4D8C7781B307A094DF1ECAEE4D2C2 +FD747BC6F7F9C6BD0E90C19294F96C8C5CFE88FB34C477574A1B1630B8CC591529E59B20794DA32E +61DECDA8ABBD1AE956CF74012AA01D42EE01E861B0AA6897C864788AE59DEF43C493246FDB1ACA55 +4C12594BC7B33657A9ECC9E3D1472EF826073F632BE540C35FF6FB40566773F3BB2204D3A579A08C +CBC844C14B18C350F003B9DA23A570C362D6003893CA32F86F59B829C78EE3188B6E3F7FA81D7F62 +2825C639638DFB78B7AF1F500F5B450FA54DBFA5CBA277C794ECE93275A3DE0B452FDC8DDC2993BA +A42F28A636008CDCB03EBF71BDCAF35019778993443F88412AD2AD0D7155A3944606463266322DBC +0244B07DA1E9C27A27B59664E8566D7A54CC03E995AAD008B0A17E2C3EF61F720CE7F7788599C4E4 +4C709CD5C31B11107F16AD70B17B9AFE2E8CD922A7428DAC171427FFAF51067307FAB0ADB530E701 +FD22DA22C4CD3064067BD4F6089C4B2C87937DD426E4E9D2F60E608288BAC9056554D04947E69200 +61E379CF5E81BFD32FD37EFAC1F61CEBEE551B0851516471A7472C60DF89DAA9EB1DC5A67E479745 +3E69B9E22BAF4E3CCA4192D603295B018C4AB69D18DE52DFDF15E96B557F290A4B8C5B1E7A6CACA8 +1F2351B97ADFC36995ABA43803A6E5AC04A3C93495F6D38106B8B144449C07D1358210F9176E1565 +72363CFBDE576BFDF99FA329DD1346E83F79E06CF68250CA57A68931BC7F342AD295D0CBA17AA95B +B8EEB53EA6E8E660B814E9F857CECB14F44A43288B69A9E7908D55BF19E844359879D28CAEF1C38A +36420185D20DFB32C2E002202800E8EF3D67C5D50E919657CA958B538D537D503444865331D79BFC +40312068D72364503BD0CC84B5F30A74D8B5B6A26AF2DB764564FB65A6BA8F9051AE2B4EA458D46A +4569F30C6E77DC097356770362E6CF3F1661074778EBB44FF7D1E3B64FF75E77E11FE525BB121C65 +46CFD13300CA1F02D571B82A5825E6226D14FDCF27F06D87452A8B6C5DCA658535CEE2A795E58137 +D48E566B69D53A0C3B766E84C51EAA221C46999CC8065ADB2F129D5B630FAB1814C0C33B5AEA0EFB +B6E994D80941B53079AF96D90A0B924F9B0E319BED9836B8F9053F868363D3CA554CBB181863301F +8CB940872ED5FA7BD18CE39218B5AD8AC57D0F752D941076B1C64D99BE0DB86D7A6D96510D772EB2 +4C587F11779BD21CFE5BDE1F29C1EF9022B2B8BCD7F91153C845906722477829C40111D810480F3C +F62DE8DBA7FD86CD236E656618CAF6FC46827FBC4898EA7672F8C9971AFE43E0E01EC8B77D4AF48C +BF1210E98C1DB15C16D149BFF58AB0270CF015B107A3A50F5DC8F37FFB92EEC8CB6778DDB7CE4AAB +C464C4AFF654223006A550EB52485A23D2B4AA7198D3CD54418102F1E9A4FBDE37B841E56F5C2C53 +966DB9B66B000E4588282E3FB80C2C519339F0002D2F83C979EDC5827A3B3C8EF8810A0F9DACB6B9 +998E9AF6551F56313DC4011904CB979AA2D32B11A811BC248141E4B9734D9FB7982A5671002D8279 +CAB93ABE057474628DEFC95D43890DB1ED34CFA8A20BDC3D874E7679A396158E522ED0AB969A4E3E +C7E4474E192590504D54DEB7B260B7935C4E56548A7D121AC1F741F8CDF259EA1B5813175A77A1D2 +D30BA26F65EB765A04C09ED51F69F41551ADF399E6AA2FC09788137BEA4913F17B8EB838C38FB272 +1FDCB55FD65697FF0B850E7D3D1CE266BF90F7EC06A9A0876BDFE767D3A918B092FC78C775F945CF +1F96E859C03DBF630D9A940939654C3549D8F7921CB94EE23D5A0535DE9DF31EA0F937F860B4F220 +A99ADDFC343D7CF7BFA0B803C12C26403F0DCFFC8EA786D0D8A8D9C367419CA8AE41190CE93A8086 +583A1E6C9D70B612C84D87D2EEAA71EC2DC12F4CDE6A821303D5F6A9BBDB7EEDCD289E80FA3B75F4 +7F481B50719DCF4A142069393593B9AF9CCEEAEC56A35B8787193D7C88113E9E1E221D151E093B01 +9EF89F6118BEC4735103CC8003CC5AD1B6727B3226CD44C497DA7052DD681695DBEC3397F9598C91 +77701C73BF0594CE93F23D50EC5BEE2FB9DA1FC966DF148B27B28EE3C89526DD6625E2887F9FA076 +7C127C609EE315626BC14D274FBEA56528DC06A27B2D476D46E9E7916590B156A5DF04A6CB15E362 +45D77021767B6E5BDFCC679670263FD891446C3371B11BB6E1DF60F960AAB4149D7753E6A5C33810 +C42C8BFF4E935003388506F8278BD7CB672F132E065AE684DCA0B9064D01DD620E7FFDFE04F14277 +EFE8E60159BA0FCA3FE2F28B902D4AC275D19F0AC6971EBE827C4A232D87650D2688345BCA78F879 +077114F0463C5F058107B669566F8171E4E284D278405580F04BFFC9902784216E0C9A17AA9B2935 +E66E18A783F723BE044389B7E9D62AA36818FF2EA406C3C1A9D2F3436F3EE7DB8BE86AFA8DAA6A4B +1B84611350D8D27605509612B515E16AA843164D5D0805E36A2B9EF74C5F6A0B9D59A04B55697123 +27F4B1B30E9587CD103337639967CBDC655AA46E80D2CFD24BEB50815B5338E522B3A7AFE8362AB4 +F05D8BC52BBA9C5089ADA8C89529B0275AF422EB540D31A938B8740860756325B966B36817115213 +FAAF92DE63F6BAE1E0064BFBC5588098B61EB83C71F1C2082436D37DAF1ACBE186FEDC4BE7C1233B +6F18BEC5F99002D21CB7864E4811F7AB3C03003E1E4490AD1AC793BD28FCD5EF0E6CC30EF39A08C5 +2F71939B0CEF620DC69E31E39D6DB969049031B0C92EF2DB653D97F370141456A52985076B268652 +FA2648C792780BAD637C4D7581FB2D62011D57E293719487CF2D1F013CFAA532E1C2D39178D51272 +A6AF041440BCA174B5CC902BD7390C7D3695056CB4BD7791F9FB6D88E7A70DEF2C97869F5DBC5BD8 +23C517C7B7C39D624DF627DC9653EA5347BFDA80B723F05F6DBB4C9EA501D862ACE05B9DBDF21B70 +56FBCD8C6D4B85873DCEE6166C8B5ADC0316CA12D9639F361B15A42F00E1D62EDBCA1111972FA0F4 +5758BECB31DB38316F3CDFE1B41748C93ED58B67E9B57ABBED5924A6D53E99FBC9A994A6489A8BDF +13EB685548B4DC6D62DA7426C22227D4D43B6FFC7B5EA91C896730253E8941AFEE588359C2BECF6F +FC415B9EB6D31CCB0F6C7F85853E6449FA6D627A97A3CE8303F148393ADCCCDFA2FE085C6908BE5C +3C05AF00A6F02840206C3253A559AC5C049BDDFD11AD9B118403B84DA10AE3C470CB9A9A2D1D7B73 +2F59F5FE146DEDA60AE750F551AAC934621B4470E1BC324C436303E25F81D0DC3188BE0D6FEC5414 +C20E4CB18952E12CB6423DF7124627ACDE145500D77A97A8BFD9CB50D1FAA008E2CE2B2505A4749F +1EBBB092C347023714055A9B63353AF9E7FEE05BB54C9843698101F79888A91531773830C2C967B5 +88D3ACD2192883D5CE3962D51084FC653EAE2C5FB2DA41DACEFB5C76812D2EDB5B109677289CD199 +8D457FB1023A19AC67295BBC1A9A20A426B06A368DF3C5DD083CB1180D287F5500F2C635EDE157EE +FCEEC5503447382D15C748C1E35F68753992E5C90F900DE54D18F8E1B355D1076ADFB1F3590135FA +D1A36F028E44F48ABB149B80CA9A54614D467F8D71CB310BBC7AC7100261092DB8C5BFD39E0AC6BC +2C9D6CBC3A8C05FF8A74CB21608EC4A4CFE4CBAA2D056DBA14206106044DECF59F957EF8A9CADE4C +9B19D8D30DD4FDE6A9548E50DB51ACA73330142153FC36B69C1C8D5B26D0C689B7040E81AC2C864F +D7C097C99BE5953843E172C97AB5684F35FB03A725A89DBF371F08DDF40A1531FC1B676DB0E1543A +EC6E97D3D2E4AA3D5831D8B3C952ABBFA112352814FB6FAB61A0D680E6640F6AEC8426200CF61286 +F7422CB2F78C61EBAA36D47EC16D7FAF8B4AF31D090CDFA255D9D7C61D46CFB22A7D6E1758E71ED5 +67E00CBD8E8F468DDFB477F091A2F915627F22FF47B876544BC1F03B6BBB98385F009C20BB1AA2A7 +A78674692B8EAC2E3C8069B79E679338DA57F72976810F845BEB6B9ADD32B95D78E5E60F16DD1668 +9C05FD82D36A3115BE8ED494A74DD211D58A2CDF983FCB9CDC29BF7F0E29988FA23560EDF514BC1D +183F3B2A22C09FB179B47E05ADEF48DF02F31C29875D1915037B19407764A4292FE44E741651A8E3 +BEB5F0D972B6327090F664417C84F84FFBF0AFFF8B1D85C822D90730AB4140C42A51AA8B1DBE4398 +4EA8566040EB8B341CCE23FD3F69DD235A080BA5C69AECB9BC732BC2D7D40617DDA6B79FB6EE40C3 +556C7DF9B23DAD89E94054B1345DB8402AE679FC4655A4A776C0150463F8DB2BFC0608EA1F124E22 +1DDAE6026B5E5D007A7E4A0D6B3B0CF3A2669E67C5E4F01551966A7BC48F2F4B6A87E740D8095E63 +F77C7A027F26B52F2299DE5B8A2F6209BCF3D31CB0235F998F781E5CC81E31DC424E008D46EC0920 +2951E5684804A0592EA47D6C788A20487BEA2EC8F2E6C1D7F378B62DB43CA43C4B366F8B4319631C +FE9854F0E10321CFA3B01C873584863BBEFC23C72C05E695B56E8A52E89AA2DAB543834D34DCAC5F +ED08DC51825C5257AE59850D101D84F4CAA1D29FC932F9E0EFFBF7A9A7F3685F61F0490CD3CC8988 +2DB52A757A6AF4C4E67B407BD2316B1C0FFE7DC54E43C87B874F57E4903334E2140B011484863CDC +ACA331175F2CF3D72E0042855983AAF8853D3015E870FF0807014C31D55060DF3FE1FCE157324481 +2744AB51322444632F9AFDA6706E320FFE82B8CBE242A19DF00CE73EE48E25FF49D5871BD3E60652 +298FE3E8D400609E232E0DDC794C0579ACEF89E841B2EDCA50D51151F65E8C1CC3B01EF1870558F0 +BF5743718C3E068617E81BFE120C6CA16E0924BFC2541177D53671CAA3AB641C41557DCDAE1A3461 +47B5E999C4541B08B4AFCBC187AFD653D5B5F8386DF6AD8FE69E21BD0567DF494F736C6A184FA4DE +48DC9F347787CA96E2E00A296C2DA05C2AD9BC423E9CA428D7F1FA12DC9353A302FB8C529AF8688C +BB543B45B2717EBF8F6C497935F4F3BFFD285E0402AB7544B3CA4643AE5A8B5250ED987A95FC1F27 +5B9707ACD0641BD0EE2AE9758494F8D8A51DCE408A38AC20EAF0852D72D84D0C6BE973326793AEB9 +55EAC6FE0A2813A355DCD22F6F2CE56588D1C055CDDFA98878BCEB6A018DB22922D2B600A20F8184 +2E665DF41013CA0947C4237C2BD60A75E2FD1A3FB8C8FA19485730B87461AD466ACB02DF8CA24091 +4FB090B3D2B41EB6B8FF05E1A59D9FD668AF70BA5BB72778953BA55FC5F9F626043450E1D09BC83D +8605098ABEF884639A37809A32565CBEFB3FF39EE53D6C18C58C272BB928E4410E361E59A50F242D +69747A032617C52DEBBF62364AB5A96EFAF642D9D82BA679B1D70FAC10A4EB62FA5CFC308E86368A +AAD7E75948F43598CD1C544A0D4091374D7E88D4522CBE902391641327E888E7748FA889DCE67ADE +61699E7D77763681CAEE9B1CA8837B2F7EF9C18CBCC538C465C8E2DD34616953CCB6030A222C728B +834911C1A179E2C770289407AB28B303E724D97F747D6134B425216A64C6E0B60F633E2B85300047 +E4C90339CE030A0FAE31E830C8ABA5AB3386A3B69267351A7BFDD66356AE5E57FB2994452993E90D +E7C4E260ABAB93C37831856A650D56E44172FECA01D6C7C380F250B82473960D2A2A5FB6B4DA668F +46E624ACF7FA0FD4490F485D640A3ADFC9F8652E7A38CE5799F770C3606DB4B8B947F93967F779E3 +A3C0572F13A5A187D31D7BD12A5C7BE23CB6ED6192086241B76C5BA6983DB9C93E4B208D707D3760 +F03CD6272EF3A4CE89B8E52E6AC5871A3D03EB975759AB4BE239E5EC7842CBB333E692CC607C722E +185D3C39164DD320C6945629C70FF66A5237C0A9520A1FAD6EB9816069351AB0F135D90CC0982B14 +7D2294AE4A38A527EE40BE9CDE2512AAEBB590E134388BB171D0956A7C4566D65A9A041BE6C4F883 +6B3EC3D2ED1B48B566A783292B15B6127920D247D494F070BB20BEFF60640B11B276DDEEE49706E8 +B2B21BB40B7F00AAFC594C492C25DCA774E0B80D82E927448DE2E74A9D0DC7AC9260096EAF187B6C +D6AEAA6D1DC4205B4411122751A5B22688404EA7C5861730371FFAC10F5AFD4727A0E402AB5EA757 +606B75EB86A05E8F774D6E430A1A3FE2A37EBB06700474239FB1CFA05EE44B91B82244C575B52E7F +AF934B04EEB0D933FEB57EBE326D75821C8B23EAA85B583AED4320B7F04B9F2DC591091216FDE52E +064BAAA9C2C9D9714B95A4558C21F3CEBE624B5403B31508F178581AF6863083ED762F1E2E34A45C +FDD71660D626FF8648F5D6C5E580D4765A67FB6159EC8077A9F0A88038C8D3D7C77FF0926E2123BE +874F7BCAF129D55A5B5960F824BD1728ABCFCC51D23936DE9A25C408D786E44C3A2BAFA4423177AD +060D21D38E15E23EB6FFC0B4120E814695D423EEFC2744A1FC81B4DF89D76F0A6803D8B14E75538C +AAD03A72517B86514F6952F6FD619D9E910D980F00964DB325318C045BDF79647F453D4A5CF4E61D +D5359782827229310405FBCF6107C3AD9DDEF9A9A339D5D5A6EB2E7838A0A43221BD62CBDF732DB0 +A638A52016FB35BA7761AEC846A023D3BF2D1BB183543E81EB7CAC1E5970CDC6F068C5EA118C7AAE +528D1396E6DC939112DA4460C890EAD5C01BDC438F5BB734218BA6270ADD0DC1778FD8AB16831D6A +302B814A1A44B07EDC65956C9E6CF4875DF521F3CE5B422F71081B6D69BD270F739095C9E81C0377 +934A8BC6390C420C4E4CDD9CF7E32544C68D884E15ACA3BCC07FC8C132D8FB9D752C15D75C52C288 +57E2EA461A6FCAD90C56843513F74461F18D7164BC597A28AE4BA7C86EE1703535A9B9ED50122627 +71FC12F102E800E0E1AF7BB46681BD2B14B614CEA91B7B2AAA35235DE76C0E113C92688F8EC81277 +D58C3406778E1EC1CC15F1CD9A137C8FFDAAB99ACE3BFC782916F1A877170589A92DC921E6740A22 +B84DC6BACDABCC76E64C79E3A588D80F8F4D376E1B426F15751CF7391102102F0AFAFD8B22DFDEB5 +48AEB5F30B1673023D22054A13391A0EC08DE6E7B685A0D031AABF20B7C62187C0284892D5EAADF1 +21BA28263EB863D5E36EA9C06A77CCFC0E17F593961591F84D82AF823EFE41044C8D606FEF83CCC7 +B0E961E7994DF8A3CC36B209D953E250ADAB8D22D7F2B4E2C9CA39EFA2D93E56195C1560E30A5190 +CC5B17FAEFCF250DF79F6B624A4B917E11C332222FCCFEC4F6A47BD9E75DA9854FC3F7AE554E91ED +DE144D7AEF38A0E3EDB5E5A5626374DB94F022C8CF549093041DE00D7269B7CE544E748439BA2870 +718C08E58FB4A77D93EBC04B7957D272AE1601D41BF85A2BADAA0DF73B0D3841D4839C85677FB2E1 +5F1D6CE592669FF4BBC9C69DBA334DC37706F2F6BE83D5863E8CD6A30C08640AAC4C233684E66B4F +E6B62D4A8BE9D531E47BEF5640D9B5C27D990092BE1597F6995C8A77BE9C18AAE6C1CF130775DDAC +41D34438FC7AD8E042CB56CBF2944932EBA7D053E9376FF398367450E35A1945FE23E05C921096A1 +5454721FFD0F429A3E06DC3ED36F1C170BE79C66996EF8337AFF85B90C5D3A4A94455AE9FA32E211 +7A63E59001F052D5F6223125BFAFA40901E98960ADF7BB886729DCA82FC3B8CC52B37FF2517299E1 +D769057F8154FB95582F02CB0BECC873A9C71796ADBD3E91324FAA94F2C41CF57C30B5897D031C02 +D256C909E080E70BFD1F32E69EF67031138C2DDCD1A8E4B65E485C23C3E450ABDD9815512D6F34A8 +4B9DB715DB2C7A93BFB424316E1AA44397749CB01088428F149A3B4324737ED9957FD388248462AC +1B2610D72BF5C073ECA567E7385CC959E37CAC7E05470160FFA5A9F63B8E9B082937E911586EA165 +374938F492EDF28CE6020953A5B5CCEC7737F9D9CC8538C4339567AAED3794ABA3B9F4EAE65466E8 +E326F6C399B36355935FBDCB9972F10B13494DC25097FCEC5A6398F275C8C151558E74C5175F7BAF +4155E36B733F75CF9D5C5979B0764F14D8306E06BA24BF791141E404C69F3F8FCCD91B9C58C2C671 +AAE7D4F9E5D6414E46ED633A5F78AA5BF04E652246A066EAD9E582B181CC196EA2D3CFAA383B5D0E +4CAC9336E119C08CC6AC55CBFBAE147C623B400453BBF447E96DE036FC025624384359EED7C7D5F7 +858DC0521377CF647A157FC3F188DE5EEF094DBA125510FDE34C570D7BE76AB5DF0A28BF45DDAADB +EA7EEEDB936332DFE93081E0AFD3FDD46BED08D6914B2EFCFDC41662A33B90B03D76D34F48D30FC6 +BBBB600E90E6AC7243FDF026762A44B4D6E4ECBEF48C9D7B696AF29EEE063E557D8FCF0F09E0136F +45D17E608DA36E59F2AECF8493F8D62536119B5F7E1554DFE3F6E8D7C9A2C6F557D18B4AF92C9F6E +050975C3B5C54F9B5F4E39D600B6FA2CD6DE203A174028CBB2A201AF126D1013C229BB82CFD013ED +199D01E51EE2780FE896E01C63C655087A3E61A7F1029FA5E97EA1872F1B45F22282DDC317E17926 +7368CB52DA9444F6055A3C653659CAD2A1D8712BC2B1B32C1DC6906D957FB88524EE066156ED6BDE +B8D832F9338F9912E29A250A8C4674E667C1C278B677AEC9972BE83CBA3FB779893FCB8F81A323AC +91474BA2A2334A07BB5628E905C518E634F6761A3289056F83D5DD7B3890987EEE1C18FB2D379CC1 +905F1AEB3B3D2AD578F0D6C845D2D40C4BCEE3F71C90E68E5417BB8CDDD878D83BA80AD8485F4067 +E5C3CABF28AB56CBB219C0AAB8FFC6C7E192BEC8CBCA1459AE4450AFCC81B9548F40CE2622E5A7C2 +81F74DCC02DAD57EFD92D072318DDF05BF42F1EA8163071E23949B0179CF7DE64677CA99B23CB926 +B3E294194EC13397EA1DC9A5E1CDCD828156CD71F81B64167D4FB01E6002713BD8AC6F82B20CD369 +9C6CA4704DC5C65A2D66EB155B7AF1C9BB46469416FB49C1C7E17A30A5F045271D7DF3FFF2F42C6B +470701C381E3456A500C6BB3D0E47B4D91C5F34B49BB6272F1F8698B307D89EDA3A1565DAD1C0864 +627560CF922DCF5B34C67860352390B282F95394AA2CDE0E97CE3ED39546A6AF1C52BFCF81A29BE8 +2C47C99E8050E4889E4575B75F39E662F2DB7420673797E2ED3D67CDA7AE2C15D0A0A794D57D168E +BE13214E89E0209AB2C0EB7784E9491AEFA3C02D0DF3AE5365A0FC4AE023CAB528162C7A1B173664 +9DFADDACA8DA5FA18B7D6489E4229E9E24D38A620464A744A5C60F6F9D334B908706B738AED18669 +8A8B278341FA4D65A0A88680BA484694921512F7DE93337FC1C02BBE6E64AF2DAD07603279D87329 +1D1F4D39C1DD6D89C90F65240F4808F6F1115CA55B88E242565E59F3BBF1F10EC7B88872E9AE61D4 +4CAE185463EDFAF7DF63DE4D2207D307AFB61501892965170D2945846FCF5973A1D458607F50C15E +06E5BEC715E0C156259AAA6C735593E5564F65F443B78CC7512EC35A56F126DF9D30974A40872E42 +65E1AE5FD483CFCBBBA26DEE426CDC4721F19C3FDA86ED7AD4FA1120F63669BEFE7002B128CEAFD8 +C63E8AC09943B6CBDFB3D2476A026C00A8FF81B1F651B97F310C82ABA5F388CC1DB5AFCFF5996D52 +52A6A42FA4D972E41EE56088F78CB966F9051171C472C774879AECFFF08BFD9CEA40D7C298922ACE +64F28C14E0B81F4DCADE81D71DE3983D87D905192EF13CEE71B2D3FF1A88AEC671EC318917DF98A3 +C9054E372D22A3CEC82FCC217F47319A40900312F6E32B536B9E7A7FA0837EC65CCDB5FB0D414371 +17596CB39D9382262DE6E65379D3A9709B2CFBABF5FC5D5B352425F06F88CD31012A2A4147B112F0 +C1C0ACCC808CD625E0228EEF66661F70AF96D3DCFECD402700E4F6522AC9A856DA466D55C84F65BE +2810A1565163872D62EB81333A698ED7B68352CACCA2D7AD38AB55C19E4F5582F75818302F5FDADF +1DCED09D94872F2D48FB636C8E38C7563C72C771A08C6B1F041F3532BDB39006C89A33C09BE1E3E6 +03622D891F98010BF1DE5355F557A1E09448D486ADEF565705277B31B8BF2B86761E32631E3435B6 +88B79D566F1747BA456DDB43CD239FB47FF7B425EAA4C657C8EEC26EE01AED07CF916E77D53634C1 +37AEEA009C6B515B6342C54BE2C7B95955B1A9DA277A0ABCDA2346E88018C726F481F71D6011AA42 +F8852F2E5749518FE3B3AB668213FE1A05C10A1C53953D75312631D6BBBA01D418199DFEFF8CF548 +6109B099FE8E2F606165FE30F532C03567785D5362AA873C9D3EECEB20F1945D55F49B0CCAC84967 +59FCC7292E46938943C262D78F3212D3F9D0F7B103157F423D71B1ED54B2A603F4C269029918F238 +EC6828FFCEC66009DB9C9E59534EABB183F31D7AD4C57B1BDF0BD2CE5A421882BC10CC1BCE6A970E +2B586BB221567CCA483989DD0B8DEC424C1D1FF042DCB7834423CF244EDA28D2D969B17440CAEAF0 +24A6119DB010CE366821AFA424D1B8299609C04148275AE6E5257A7ACB3C766C747CE99CBA2D703C +F19B7CF301B634D8B613DDC4AFE4633A4D77BFF8E00CFB5E289EBBCAC90A24307E7941EC1685CBAE +400CADD876FCEF7F6557EEE167D2035A05120293527700DC510B038A496BE1D5CBAEF24ED39F7421 +1A93AADF22214ED606A80582485AFE358E3A46D0671148998A3B3BE209467009B43400870359D418 +9A8CEB4D5866AB52D16D9CEB1EAB71C07E6CAA34B70E3096BF7604C22C40D5FBFEEA616DA3BABD59 +DCDB97D883FC8742B8267A16A99B7953225F7144568D566E64542C92E538AC140C851E5D295528EB +7CBB49909B1CAF6409C9BCCEB325468FA0B5F7CB2987382616B477CCFE4F4AC79E4A6F7165363543 +F04DE5B6F6E1C2E910CDC3CDD6C4C92737198F892337DCB6647BD226C820AC99C65D8E7772BBB74F +E65DCAA8A22C33BC168BF48E40A82700A3A7668C5A9A71E397ACDFEE7D556C5C19467B7AA69C260B +727407AC837BDB7D67DEC055C1F45D8BAC61048C45BC9FB3CEFE7549EAA2992D2EDC126FF7A05EAE +58613332A2BC1465B2BC0429162B907D65F793D236EDDD8D35405866D71B25F62DC4A7E06D4DEE82 +840ACCAABC0774F8A63E9C0F7FC980B3583E7A8B01C46590E3BC04EBA565C2EA94F057D964A78A90 +EA9F52ABFD70F84E44E434BD10A42E98C794065724341F907E35D3CB257161E01C7084E3A0166D15 +CED65DA7BA87DBB2EA33D39BD99AFB93D3548358D08330E807F8552CECF63C84F805205491BA3A1A +622E70C232FADF3BF2DCFD6F0539158D3306506F150B0518371912A25EB96163D73E9EEED42EDC84 +D688BC7F7708D9DCA348FAB4DF62E5809BD094842D0A31DBB7C4B41F94D946810C5EC10B69AABC2C +91A59500B2E5D37F4755DDFB7AE4ABF757F4C5BCF77C7F95E6A616646456FE8F18407080BCABBFA5 +7704287AD26222DF91AB2613951E2D679472F8ADF06EA2A20205EC19972299A78BAC52114334470C +5F5890C2F846B4C6042D73945127F2E3910ECA1C4CD7A16EFE4B4BE38A15AAA710682C3836A8CA83 +FD384970139D8B46FB0AEBB002DD224199672FFA02250FBCFA4E649E335428FC71F50F45E498419E +DB0E970F46894A48F65580881C9C4250FCEF65C9B28699408E18B26FE6DB7F1CBDB767564E73CB59 +54C6D639CE33220C894F36E70F71C9F9AA3FE2AE0AA0E3F2E304EC5ABC661675CDE2E70519E4220A +E26FBACBD01D5169EB844750753E6CED53E3678FDCD08AB93E10067E9C64F38B40B76D99B6CD92BD +F4155A1EA5CC824998B59AAD06E09E5F15EBB2288D66EA71B296616734FEF2796F07FF0D8B047074 +A1111D68B99C2B70FC56E74A51B062F4998ACC85B1943C9477E436E5CD7AB18DBC898D21BB93475A +623BDDA71D7B895BA2D4C10F4B90BF335126F4FD57D73AFA50170F6B3C364922E551D40E35DA75FA +891762FA23401D39260F2E92C7807C746F13BB35CEF9DBF2E76E66A72FEFF095DA482A4DE8A42091 +7065736CF4DE904FB52E649A32255E2030A7B31B686353492F31C064A3C4B0448C4BFD44B8E15384 +FD809B8761EE26A7DFA1758D57CE4F0BC376EB2B3833534B15A83436BA553955ACB5A7A66796AC5B +92DB5388BC53EFA27508B08E82821E5CF669BCE52BB860780F749B4F38ACDF5FF12726BF3EC2743F +01014CDE96FE6B4C40A034E9EAFCA2A35CCC776C2669E6AD138070A40F48ED79136D7FF57E993E09 +B81C543FBADD350FF5B5F7A46F060F88E30FE2D8233832D18B6C323EE017EBC1DF5C838321CDC8A8 +4CABCAB20B60A1A3AA028F36EA6E87C850AF8AF7CD50AA6359038BFA8818821D02CEE8F51DAB8C05 +F7AE9797814D97F3DB8CCDDE45B21DBB15CEE292FAA534A5F317B357F4091F3DA357325B8B9F5EDB +45865415973C143E5E5BAA483FBF2D06CDD4246675EC58B84C6AE65CA743117FF00F229243772561 +31A7F2BA26A9115AFD96C18216CFDF41B7220ED0CB3FCC26C36380007B382A02AEAE428887DC8BE5 +FDD630AC57EE3DC156C7B8B29E687F24442E35CE10BA4087295A641F7139C831F7CCDA6CCEB5DAFE +537CC1A97C5A337D3C48A6AE947F58A30DC08CC7B58DBBB4737AD52783C573FC1E9408F55495A80E +7FDA61F0B9C4F090158F1A416249EBBA936C27BEFDEF19D1BFB839EB70576A010706D8B95657B218 +9C2AE04C11EF9E57FE09880273761FB4302C388BD608FA0C7F00F033C9C00F4E3D5CE2D903E0DA52 +E69C7745EE9FA75E2AD93DC6CB5CCFCD3782A699B807AFC36AD1F62B05856D5DFD6F88831B90EB3D +CD523582A49732E3FD7253126D39E8AFB8458B5F7AD7F94A8DAC13365F433C857AF4A42C0A08C4DB +9887C4957259ED22D13CFDF5995DA957EA5A0F620B0214FBFE08AB6D552DBF048D62CEF6EFF12F15 +3511ECA7833E0E3E95F85E6AC0F95438AC4C126E1F1ECF336ED31CCA7EB216D279877123FD9FCD8F +B5E52B587CFFC4428456DDCA816819A8A4A211D8F1629E5D42BA4C5C356E580C8A22C61D987552FA +A97893816DA73D423686E4EBD44375C257F031318865A20F22115E72BF1EB9F93AAA169C140A33A0 +6C35BD4526A38BE79CF40AD1EFA10411E8F3300A8A8B97AB140EE6734E1BEE6C8EE443D698D34159 +97649C6F10F20ACD80236422E215E146D744A262DA3FC88DC0D86FF66512F49D3F957D3C5CFFEB42 +4823509F33F155057A4C6F37B52F4667767BA94F6B8B62856B553F307E5D230C44CBFDC9A97A45B1 +39FFB2F2565EB0E22026972FAD0FB7B9576FB6F368B61979943A398773600E7EE1DFEFBF26D45D40 +BDA66EBB96A56EE9CAE0B2420C5DD83E24DBA9FF885BB844BF3D2BF93B07325DFF60C0CB5FDCCA0A +C8FB5A2E119D5AF26E53AB8E3B428481C2871DDA26EF0B621CD8572B3C664BC7AAC01A1D05B98F79 +1A7080D294BE81099BDA7982432F3DFF4775C44D23F4F1B2E0162B61A8B2CB5EE8564BF98E2ED403 +2219085FE6194C19DAC98A421826CAED7F1AB1477AB327506010217283894235D7DBFC1153D5ECC4 +8AA7293F19592B4D7E95FE55151889BCD1D7FA7DC2370D2DFE11D7E4EA34B5C7A8E73BD3A348FD38 +9EF45B6167FB90BA44C23E912F9A4F2FC0427ED070592F7110183BFDB2C400393BA7569058227926 +351F07FED4F33633BA03A72AA2DC6B598E49B96021DD868DAD0F352E5722FB714F667C15C68D49C0 +3D822D82677EDFE86FE9668E537DA284068C9B0AED83074C92A5B939296D505B837E6A9DDAB1AEAB +7455A08A114C2222B339284674B74BF4CA9EE0C020BF2A148B439C71C6BE51A94CB64FBE4A7EB295 +5A455047CF5CB348B062ED4F6471CBC3E9ADD9BE9B96879AC7BC71BCE02FD02F17C6063985A5E898 +3D205AA1489DA13C408990ABA1C54F2F501AA172F530480D789C848118C0A74EF98D5F607A067BAF +F6030D887AC6A6497F9A0B38F9705F328AAD4BFBB634F739386177B07F22D5771282444E5EE17335 +B4D0EC86117C697E79A5F4F65FDC08E4904DAEDAB20067EAE2448FD4301849E456D085F392DD1316 +7ADF75CCFDB723E2904A9C0C976D6B84DDEF9D92B0E15FB246C3ECC2D0BF314CFB957757B3A3E8E5 +801F520644E4601D291DA0F7507C06F3B9BB36FC1C70EAA444E14E56C0CFF06C7F853DF36DA9D8B6 +AF2544B853DFFF535A7E5C6FC145250CDDA229956019659D0D253A19A7B51A4E538BDC01F74D7704 +9949C2C97C7EC6392C2E61CCC0992B66DAF1AB08551063E53180D2A67DE496716CCBAA45462D9F91 +B66A22545962DDAB120511FF08627131B95E5DEEB8B4DD9643E7B2AF65C0FDCE11F5F1E8DD468DA1 +8D41C8C4F00EA73836F4F70EC50FC3EC6D358C0658A4261C6D15A582A2C7C994E7882E661855B352 +014576858A265FFBC425160669CE159D07EDAC04D060B44E5800A7AAE8E339C29B929AA81D2F515C +46229D2080D5917AB20AB6B34FDCA8E4AF64ED660A3173786FB1A1D005D575C2A5187D3F7CFDC94C +CC44A38C5CD523E9DA726D8EFA6DA7B6131DFF3435FEE838B2C7D6B97934295F06202D307FF78D90 +6699CB9C5BBB10D1D4DEA5FDA5BFB094E704607083B646D37F5DA1FC7AD21B813F44D8C1AFEAB666 +55AAA19703BEA2E77DF3BF350E17C74B3447A452235919452B5175570A006C7680AC05E8950A62E1 +1D7E3ACA35A397D1E19630D094A86807593C97F4C484E4E06BCFF708B6DCA972E3A0009E1CAC0EA4 +141530F5C1B8AEF5E1B933F37FDDBC4BE22B74FE346D1A3F5FEC0818F8E61765568A2AC04713E828 +F98C449D9A1CCE52D10D61DD8BFD084C8D099A75D89DEA64D5A7CC68BD5B0593D97953DADA976383 +F5015915618AEC56D71D1DCD55B89736395C609B315A3F1E1255432FDBD37F38CC43C354FB4B7C44 +F1A7318B0B7E99C3C08C33B953727B6A6328051783A0A33E3CD9E498346A3CA6A77B517096EDD52A +E443B87643A646C3A7BB97F742888D33F9B3127E61942F4103C1DBDCD8EAC8F9E259773066736CA6 +53CE57E8822651261D847C131321BB9D6626A1AC50D047C0BA47B411DF2A995545BD68EC0287CC9B +31D5DDCA8755EBEB10ACCB3903AB0FD5788E984220443B8459E7C078DA4289F1350905881AD6DFDE +C47302B0ACB0D4AF8CAED02B4B70DF3CF8FEC118F0FC2D3DDE3E494CD160E676E300BC464BD4400D +B50EE43B314E0517037BF971ACD7CD327CB2134893B8A0410E68DDC518F5DEC966C7884CF5FDFE74 +723177F20DEDC039D879056CAAB4BF045062D3904F615C5CFE109AC7A35599C94024B41019B9AFD4 +04A80ACAA4837929F5C9317680A13D157A03B59A5588DF79D2E113F5F51021D6F6F90E8BBBA2C252 +FD10651BE80BAFD59C53A3367BA3C28DB6EB9DABF1EA99F47B503F627E15DCF3FD645FC52C5D5D0F +2F07DB4C25C0D1E1C00146E1C4D973E613CCDBD3F9450CC0F5343D79F05E9492E86A1BB889ADF405 +03BD7F3E7543436859184A5B20BD8A172F350D846B7570803990ADAA48D4B9155A2B4C4BFBEF1E1A +065C08E03928559735BDD442FF1E83E1FA20A5DA57D8BDB2FF5427C034CF0128AF111E6E73099E04 +6E0C240E80A73D7BE72B87834E45898D475521CA3306707631F5C6136199F354632D1A085F12A1C7 +C473868B62E534D15F5484323E63D0574196A19EF175214EB35A90873EFCFB92D6CF68761D45E37E +AA61E1A1979A82009507CA193E44B36A806486665CEDBCF387053ACEAB979BD35D30978FC7659ABB +E844F4ECAB3303318ECE80777A5FA5A9DD91B3D06804C4B4E9B4EFCF07EB89866D0DD8CA390CFD15 +98651417114D78776B1A1D36B4BA17746D6BE7FC123D473EF1EFED1C3BC1D555F914536869FD5B0C +35F9C83F65B0E6BF7A627B9202D787D72C600DDB6BCCE613D88492E13CA0AAAB196E8A49928C62CE +A4FFE2D0208EDA334ACF47F20BD793124D2C5546C03F4A364369A76A0425262F9D9118AF54E37D32 +E33AB25DD533A49DF5FBF1BAF4CEAC2D9D378CDCD13B00FDA432D9042F623DA41AFB80699B5538A2 +5403B0B3EABEC9E8EFCF42FEF3EA9F91766902CD206B0787C187D5370B60AD6DCD002DE2DE8DCDC0 +B4719A797C5E26BAA67665016DA0D967FA1346F9588AEDA174CA001B31213617FE19EA218EC23597 +79D979E2663166489C06993230B0D07973A117C4E3F4A4C93CF8428248DD5389414D679C69644142 +67C7FEA17E35B0CEE456667A9B1875C81B2302BDDEA2818D6019FC1622A82051F60584ABC904CD91 +8676305DC03FFBCC64FDDAC8D8AA9CE2EA00D6C97BC63C8A617DEDFC0E40775649438E9F61AFD179 +5E3B20560B01BE5E0983F136CF48AB206954E41DEE0D9DDD953DFD01CAEB569151D6BC0DFEF29D70 +FAE3E198E7EDD8922C0E0BCB8BCCF1C016142C1A8B337AFA7A05A9D7534B184BF3BF827F371E9BD1 +9A71244ECA1BA73D484CD2FAD54DB2F0EEFBD54B536EBCB5094E6BC2F5B2AAE41F05B4B311115876 +ED42C34F8E643B53372E3F6350DB8A38445822EA9A33E27FB0CC42CEDCD1FE2FDF723FC47C996EE3 +56C402112F24D0AF899B2D00BEA1CFD427998BD22B2A09046D6737814448ACFB10D387547D7009FB +384AF0562C85694C071584236D0F1F3D3FCD0CFB38B77C81889061E668BA7AB37AA60F58A3967DE2 +6F939B79CBF10A9DCC42852561D8D6754F1B660D216AAB1E133FBAA321C56E2584BE5C9BAE20CCF0 +0E8DBE6D9C2FCEBEBAD945C3C04101D2387351F132628786F6D9D4CAB83419288D31F9BC600D9664 +12E6AA457CE6CAD26A4C0671097B98C2384C81DD8B9A3222D4F4BBDA7017895C3EDC26662779AEE7 +40D9D7E24185FB821970B0A3A94041A69E4805EC88EE1EE521981536F2844FB8F5EF645F67D42CE5 +148E2DDE43AD5AEF200EDB3A2C7866C98458A92666E5F9E070178BCC39F65A893102A10564AF4E8C +AAA5075D2F8CD7FAB0401C03AF299EA3515CC93066744EB5AF7CF0ED06675BF049A6E3C211A89E16 +DE5BF0445A7CCA6EE8EB0347454950485D884606651E5887FE8B24323E2AA16DE22FC1FC8C4F06A8 +2A1FDE5758976024068197E1F4506E4D3D8A16D40461A4586338B374A592DC60334402F76388AD6A +457DC3F54E6169CF7AE3959676E966A45609621055EC3AF80E182633300A4418E34A66DDFA6B569E +5A13C9115B5FD3EC1CEBE50FBA247F60803AA83976F00117536342DC3D9890C49B2AC701D370E43A +955118967827760F7091469C5406F08F18D7E3548148CF0E312B1DC71DF67A5E7A1656CF2F47F3AF +F3DD50FFC2FCDAB7177285B29C17CA43019F62AC6FBA52D1493ED7C427526470ACC8389BAE827759 +4958908F517B2863B83292EB5AB3F57FFFB08393CA610FB1FE905D88A0A16AC395E2A2A6DD033D6A +0D68992F830B2E1B95FE357BF672716E88FFB92FFC3D62945D1EAD22BC68C51EE0E10A43011DB94C +44685A5C4576F6EF44CBFB45F2A4BF110A01657DB51FD499767E78058199B31DFD60813F1A344F86 +289F9378231D5B151C92385E3650B4FEB1DC91018EAB8474CBF69FDC1496A4D078D2C351C8196451 +247A9DCF8117E5B637371D8E22E248C64D999015C3FD2311E9950B8EE0922FBDD3D7BFF766BFE9E7 +CE0BE12F318FF2A7B5A9C6D00A54401609304ED2C55F5C1EAC3D4B38355BBD85D66D61636FA6E30C +2E82829376BEC979A6FEEE040E452359768ECF90CC539A546F17AE906C76F14F86FF697797322B05 +1EB311A759FE260C1EEE5DACF383816AAF1294CFFA7BF87A4D9BC595EE8F2C2F86FEEE11AD959D86 +F22FDAF4CEC098942A57E57813A0FA99239E994FFF353C1E781D666B8928CFC648FCF0869FC68468 +BDBDA7D280DFAB8B0B3A4CA35B074B686DE8D372C61FB32305169A1A9912F6541DA16CD6316A6EA4 +51524757BE5CF6E820011BE3859FB8B8578C100FF029680E05F0E0BF11D33FE19460C85EA5E4C0EF +28E29407C8AE6BE01CFA0D5022BF9FB01416FFF722A784DFC8FCE330EC95737A854471D334FDC58F +AB42867A7B62836A8B56466E9A6C1247D46EBAFFB905CD4321970F59FB8D6FF65FDDD34BF913AD32 +2E68455C5FF2D23C1A5EAE687F259BC982B6A384D35440F7C693CF50B9ECAC0B5578CAEE87588B56 +2EB6B7F42034C9F2E545EC866316552354EB3728C7D26527ED75174EAF635E048B08DC5D23E88981 +070AD5641A652F2344956E9CF4C16E652A99F4A644D1787D6D36537489DA4D74E61B2FC4DFDF1D1D +9D58F9C26C5EB63200526AFD168AC57D5611ADE4D4A382FC28BB60F9E7D626A6C67AFBCCD1183C5E +3CF2EF210D0BF5CFA7BB10FA3887BDD4CD96EEEAA8F9219AA2F10ABC0A960C3B57C0EC0313AE10CC +FF1F522124CFC8D2D49BFBB0C193EAFFC5B48FB3FF30B21CB76F0A4C0F1377C9223145BB0468A5D7 +1B9BC25873EA12E1C60334571C67385C00D0B570D3FFC6C7FF0DE62C183C76AEEB12DFFEE1459E0F +C818C621B8D12FA1357E2B55D48935D70BF140B4CFFE8813DEFD479350B20DC2EB1D3CBB1A2D3DC6 +EE975D58C89D61FC50E6A0197DA9A586B72255023DE47DABEFB11E8AA02414C2FF6258A281219B9D +DDFE41BA7D7977D0D6F18224FE22F7D4E9355FDB35BF7ED3418F4F68D093AC48F7D8FE4194FEB6C8 +0B9DC1F74E023C604DEA27089F98C3973FF9F4AD7BF7BAE601DB89B08D5D8139B95EDCF6C885FFA8 +B3E4B0477E7040225733826BACFD1EC4A0DD72DC41734856AB9FB700DF83CA2CE812913BD142D84C +5C83C0B2583768198AF9E885F2BA74877A414233207234AA5F18840557CA11682AABDE8993533887 +7C6D404BDE4153C9827EB16D66C1D73A8143C8A2D3604FF72CE579FAA3C5224BAC48EA83BA848429 +9472007DE96466B5B29ACC7C03B05DCAA38A48BFF9F214DE43146AE4E04FA705421917F99BC54533 +F0EBC01849E396216B9F0794E6F6C6B61B52EF1B1950C0FB609895C3C55FF574163FC8B6B09E66AB +AED1810E698FF37CC1F926B2CDA3B48C7D77790EBD2D514B6F385D397F713EC3AD3954EA9C846158 +6031D369E8B99E53408A79D64C34EB5A56DE8A67DE91837960E98A66FC04DFA0EBDE21DB003234BB +78665B039D0A469A0221BD541AF7149A2A659C300132C14581EF766FFFBECBA8B58A5EB3F95446DE +F49AF863A8113D17B2E7E6ECDEAFC3834D4DF900E3475596E86FBB4E2974C090DB4AD61A737D611D +92B4535AC291C56AD8B1C031D2F9B505BB77517B737D70AB3723DB52AE2ACCD5DD2F617423ED3CC3 +9CA882EF41757BF7151806A9B8B0F312808863E3673FB54DE939B35CDECA7FBC4DC3BDF5A5F47D35 +E345916C39366C8B4F439CE1C6F1835C320BD1E67375B03B5DE18C93256F251761A4C8CEC01019C0 +68E34447BCC503B9571FE8000627A6B3DAD5854CBC0A2D69E5A8F46BC78F6A7B1422334EC7A98ABE +FE9B83E01DCF3C6C9273B346F3240EA225AE4A4083CC7B0EA141A0773FDE940768358EB4B13D82AA +304A1386D450C1C0C6A7D5A8FD2BD313F78F85248B5196241E31E5595F3BC01F37700A2DD3D4A0EE +2DD01A36569CD507130E8F5B1E96CB560BB7DA15560CCADF3B2C9804A11D9E8055C9EC70E48C1D21 +3EB756A1376F2EDCB7189D78CD3D6CA5865537EEC31C17D801605EFD860B0B629472690588D02575 +02C6F7A75B9A1C1B397781329832CF3EC43C09F1559CD562C48FA9500295CD3B0A790DD3FCD4684A +7C7AC49AC9BFFF36B39A9FB148BC28D37907433943CBBF0CBDAB46D3EA86DC8F81C859C52D15302B +94A9B51C199B7104DEEC9D769C2634CECF8B700CE9C04152CC59C9326BDACBEC4312DEED92DD087A +1C4840868D9F97CAC046581F762F75E8D24D6445370A3F1E0AE74A6478D9DAC37E7FA5BEBEC0A1E0 +81AF89C1BBF7F51E3E2E22C8C405E8671BA85F1BF0DF79A465DAC7EC07F731E00632E017D190A99D +83E27E5C2E63D7DABBA23B2E88334C63721AC5A4CBC5D45F4C177259F34C2EADE01FA008AF65EBC6 +01D8DD16436D86AA94C99F3CC0A2F87134E73BF22F108B825A8963B49C6C685474AFE4A542C8641D +C0375D7EFE9AC1168D9700459BE52D0DA399023E141969F25C0DAC4668534B6647EC85454BE945E8 +26B26DE6E3C4584B97A38E2B40A0D23481BCA78084FE80E00A71A790BF31DF468A435ECC88E60A57 +860BBCA3D65930186E9917CBD209C230E8F8255A7ABC7D3F043AE4D7AD63D9980BEDF062B7D5C298 +C40225B6D03F29A0339E0FCA02138E526F06B9EF47F5E7A8068A846CFDE2BFDEBD24F5A73A66C079 +18662AEC80B43246284FA4E2EE0D9AAB172B1E59A6CC46B801149D8C0DF6DEC9A55D8E1B0EFD9D30 +2FF618075944CCCB6831D336B11617107B0530D09885E5CA11A5F1FCC8D69D603DA16BEA51116D42 +CAB1AA1E4D7B9B4D79993F2BFE53EAC904FEB70B2D330A89780EAC10D12CC0C35B8399F218AC2976 +E57A26BAD20CE2FA2AE2363D3FD2A8A971747556F2959DA74A8963C20B504711AE1CB0D0C02457FF +2E9BF696B159AF031DD5155F21C0F5549B0471A3C5DC8918B675CEBCB23E29322B959ABC05283A70 +2E878DE8EF25EA760F3C5C7B7B49D398283DE2ED837FD59F7C22D62C58FE4448B1049FDEBFC8787E +67D7DAFE9774979BB3802254DA59BCC0219F98C219F84D995CA768B8B5D9D4A32525DFECE003675E +E4BD5D8DFFC11025AF2B468F9207B5B2B42349B98232BAC0759758C1F4A283405815BD7145C93FA0 +8F3ED2826655053A3C2559073D8ACD199DEA2C5BA5F616A2E48548B4370EC73493BA07E197165DCA +774438B0766867819C1154D1959FE6E01E6312E0AB91FC2E2BD240FC8652A2D456A1DE7F34EF372A +53794D4C4E050BF3CA5B7BD2F1B8DE93B4C8002485CB219AD2D029739FD3C81CC6E78EDF38723576 +1A57143EEDE5CC887F282FECD261F6A25D0A7E154ECDF5DC38E426811BE86AAA458577E5E0C5F0F7 +5AAFA9C41E5D1DC9D91ECD79B514F8CDF7A5F1A189470D35FDF4F9B8788879CCBD91B427822ED658 +389E981E0EE5F7FB87692A3E3E931DF8A1D1573E3B0166204240B7080089A09EF7487C9AEE2D665F +5A82F94C877FB5B0DC531CEBF1E71C6592CEA2401E4B5122E5091DF03D203DF979B9A6EFBA12E2F6 +B422FDF15D49AC0914D372D21E871DE65CBECD105FD4A3E4714B9CCA5C6803FA39DBB015EA8A88BE +7913502E562E5B170B87BFC8572DC9DF49AD63694311EF1334444BDF0B4CA3245271C1F7A4D7FAF1 +703E3AA0E1EA8D5C6E821B28707EE0C9B4F22F23796FE87356C58AE2CADC191F4C58E1FB58DA03B4 +5A25AC95DBAE13A293474217BDB214742B9D9D6AF35F70FED2891942EACE3E625E55FFB820543FBB +250A062D3D395BC0F219ECFE0D76686AC148BC41476A887BC494DDBD396BE200FD3E03CFA12EC9AF +6B934A283C42AA05589AA6B4A8D16946BB51F50419CABECEAEC5AEF9085C9989289E9B46BAFB6FB2 +782D84DE2B068F91A9744AAB237CEB1BA513E57E4C307108E993C972A3E0A898D5A8D27833155031 +FDB98863C3BE7FEF3004CBAA5CB60A1F2E3EB4D7290FF5FAFA088B1CECCB6CF51A58DAAD998F0839 +6CDFD68F5ABC9C1CCB8F6514107773C69C26873E889D1F79D10E866910E4684186FCD71C965ADF62 +39BA3418B313A27AD632300969B6F284519366ED85E7CD968D64823F8C59B5911A72D0A20EB72B60 +3A61E36F52F256FFCDF706B4560B4DFA5D918FBC530D83A4B3C01BDD3CB4572E24242D141BF9E775 +36693A0407D002E09CDA5B195BF1CCF430AE9824C07928A050D0B460F2704BE8F9E647A4884C4567 +0A81EACF7CC038643EB0FF18A376FF6F32B6FE4F197273327FBBDEC6443A299CAD4B26F7778A99F6 +5A11BDE047153E764039EDB251936AA43DEE50DDFDF8856519056AAFC4C5AE6F2051AF0579A9ACD4 +1D00775D7DBE70022CC263DCA5E0A25B9C7C4F5C418587666B2FE24816B1E0EC92F9074F1403BB83 +AFC3F1D52CA79C387BDEF864366E34C90BE52F7AA09935373A07E4E026224E76F9EC3CB9E7EDE50D +EFDA48248D61F3CEC880A3B8843306375D9711E58645F3625BDB8E87052DA67F9794EF4AF8DB0BCF +E00677C3A26907DC651BC838C40EC39E2B5A5DC0DBD345944A6C32226089D63C52490FA10B215AE7 +03CFB663EB8A47793B84CE7364DA1C4E7FCE32DFEF09490121222774915BA59C78C2275F829D15CF +4D8686B095C38C731B83D48738C25F40B8ADD487C350A2EBE846C3916AE384CB1050F9F5DFE09FCB +D9129C6270FD86D55A459618FDFA4F907E6B4746196BB717865AB378414029017551161A52E9D24B +E4F7EED553A927933D4ABC8F25DF607779A717909CB4D810DE8F5762581900E224E4B91598149BA4 +71CF8068ABE8744356B261600BFCC57FB8BE45036CF6571D9B2A95304933BD4F17215F8EF53F8E08 +1AF61FA7F9583C34EB5655CB0ECB82246959F09091F36989EBDD646BEDCA614B9A61AB7696B3FF18 +1058A150FA6EC1BE2EBC7F64357A3FF2A2B0491D2F4E0B970DE5B7788B467CA678039B5EF55C88A3 +84578D427FD2CB16C87B0BF0A3D37CE8ED43E0F049AF2436344D5F47C948C632C94A287509282561 +6C64C5D262FE5B24916FFEE982A69A6CCF888BD01D62EA591EEC51F4B7DDFAFFBEEA93FE08D736C2 +0129E345D06B10246A5F57151C198D407730713F32299638EFBDC01367E23EB59AAD42A83AB41B43 +2DB462652E29813740F4680A5D4BD47B18328FAE6BDF4200CFA4CE3773809B45E8887C9B2E423698 +9F6C48D64F5986F563D9A7538A8716082F81936AEBD0461E6F4BD470436D8B7656F0FDF89108E6DD +02ABDEF907731D458D690BC608EA9CED09EB1E6E64C0790C7A2378201CE997FFE0317679EE1D4EE9 +F91157449323E53B4ADA8096CD628B5861BF794543A98F2FA2AB54FF0F25A13DAD43DAF9394329B9 +5AA53CA32749FECB0B2BC035DD1EBD53FF9FB5AD8BCE06CD89E5568091C1CC314CFB1D9821D7F9AC +7C55F55E0A16E39A87D43148201B928F3C42B110FC056189DEF183745F3B637441DE8BD4C3C7EF12 +F4258E306B2877ADAEC63441010750DB4E6269A4C78A0AC01BB3603C386651FE814031CB5D8C1F14 +9EEAFF652A53E57BBD4C8C0CE36A84A319A53BC1E5FD3F1ED1EE72F4C1A9BF264B594062FCAFB22C +C1FDE3F2E3D3C17DD3F7FE0E15EBD812D550227C06D01127385374A11438ABD50048E17255FCD2BB +85122A6FB9B7DA9D5E9DE8A747FAE0DA45A1FCEFE92B9E70A5B2CAC668D4D07527A5C1403267D823 +048BE671F725CFC7474B44FC5AAA348420B2D7C23C6CA066666FD6F2208E329878D90CEF1C2E77ED +22D3BEBB9D547810B189F08920A27E7107F208591A84D463CE2576C70C3DFE6643E4EA93F4E1DAEB +41D46F0E2F56FC10C69AD5034FC9859D31CF27A3A1EE256C93111F81C11ACF1FC0CE20B90BAC9AA3 +27A5C85A7985B951519FD4B03C40BE637162AF41B2FDA68F0D1E9B7602FE2659D3D75955C579AC51 +DF6A552EB9581AC3F712F083F19B52A6C4F560F36C59CEEB0C996AAF1728A2AA45DCAD79BD7B23AB +388D5B0B64A2B95154B6259B730B0F4A72C8C7F7CC93C7D64D9D8810D1F63FF8ABD4DB89824E2D26 +4FDEE916C41E299211DB1A53256E1DB5CDD04862F034D9404B73183A99D3D13D642A663F129B6D16 +7095BEB4EAEFD03DF2FF2F0B6B594C1EE90FDB203DA89FACEE23F1BA3901FECC75FE1811BD701259 +343011262B6A0A9707AAA6316BC3C17F787BB80AC8DA5AAC942D90F80C5A3BB59E47EC767244AA95 +C63E50BF809998957936D3BF6ABC24B0A397258F9EB4DC8F65692CB023D9091FB180C69498CD0C08 +BBEBADC84A7E0016E8F8BEA325D924EB0DF82E75D2CC2CCBF039B11934363D4332C5FBC5EC556BE8 +5EE4E707CC2753CCC43D2ED50558E51A104221C9323CDCB0199B7B83454DE3FDC810D0F362C0299F +5DD981B31D8E3DDA284FEF9DC8F9C8DE138D3065437A7FE8C30572AD06D62E8527AD37AE39AAB0B2 +25F76A25F6C6505241ED73BA494CF923E919F688DDEBF193E188F8C4C154F21631080763B4D091E8 +AD1D2FD6649E0CD9360E8D1A67A5B5FAFC67547CA31C95A5EA8D4EB5D68B9F6D6532DB9B54584735 +9558542A2AE58C09F3BD2918EFBE1699E9C8F2C2A11EA4D224C726D2ACD4A8D8ABAEDC6588CF2AE5 +66528B94F55B823A2A1F7BE19000F3E7579D094E047075DF18C8C868760295533B26EB3ED90635B1 +29C17ACA679C3E88B06998CE5A7A2544B700229F5A6A504BD3E45B276471959C8A3F81917A534287 +39B5EF9E3D463B3BA7318448E2A3E79520D2D245A2A72F31FF7070B6E4624E3A5E216BD103640C8D +F387E49D732529C611F8B971073F17EBD2F6EB18F9B74A67E1997926DF178D4C9EDED435B9682F1A +279C81BB9F60DAFE125845A2FF3B02979E5481C78A45C479BEFB9FEF3CE2BA9BC46C77B50B03E48D +A6D17B76F06F3AD118371ADC69E178C52B5FB4B261C9311874ED07DD6D5B3226A005FDD7A6D53848 +09E7063F036CDEA41619122635E835D2D74CBB6AA9B38CAA4D819C26E95115FE0DBAB4198FC5838F +2C91B7A87B07D734C6D4F4F83444C1E90AA9BFC908A2BAC4B3DEF9157AFCA5248F2DA31CA87BD363 +AC25E9E77F741D4B2C6E02F04987A6F49D30E9038CEFC41BA172DD675AED8B392164411144E5B738 +F3210B0E66B17A13CB9631C33D44484E792A7C082DD0A5382F34C5637653261B1EB6D2035B08B4D9 +1FA9AB770CAF40A103629511F7B43F2743D7E583433DECFB19C21FD4FD0AFCC22A4119E77C87BFE6 +FE50068B22479015BE5A9F06BEAB4D37412E062A45E0CBCD7BB39FEE747E96306F79FC4F2E8942DF +5D9DA0E55AACCDA547DA19D30B8404FA121298B44C9CCE198C708C69A8D6BF17591C5C50D3FC5BE6 +961F7ABA8F366DAE957A1C3730DA4A5B4F035A9274675EE3BBF0CA8CE9D8349F50CABB1C3EA4948A +BE6F9F143592F1EA95404E6909A909168E3279A957AE1924245C356331A75E7008BEE92BEAA304BA +40B7C3F48F74D9018B3247DF50EBD7CE541DA48ECCB1B0BE51A455C3C13C279D4D8676078C3EBE43 +08748D52C9B041D3E7244C745B1F2F742D010A9E60695F3EC4FDC1050AC082B905D6A57E8F407A3B +472F731011A5798965B7B1A307E252FE02C8F79CEEDDEB6E165F1A94D7FFF18DDBDF79477F14E9E9 +3981ABD200FE7771B29D1D2D120EE79D28B9543818527039AC74085EAFF241B56D08220C958B5D9C +87C0C04A14D52AFD475B542D391BC54FF33DEF8D9484AFF6873BEED32DDA4B371112B523B6CE22B4 +0D1B416B64C9370F1CDF2C548F4CCBE9E12E21C36CC3EA52DA232DCFB65F66B22B5E2EC04852510D +5E264EE939BB67AEC4764B87062AEB7F680B40BCEE04AD45C7519EB3B6199C9E0E332661463647F2 +FB7EDF303EFEF84891CEBCF0FAC5F723A9D0476C3F8C092604C87FC69C7A90F4D64AE45A478EE8BA +2DF50FB93F55A3546123F0B0E2C1C40C98EAAE9F0F26B8F80FFE6E6B94B7E27D2884D58B8A119662 +2DF6BE608C5569D7864BB756DF2EDD184B90812B44ED4A32D001C31383A40AEEE9743651F7950846 +15C48E402DBC01C818D477EAC0347795CB2792E9C11E8FD4A02E194EED1C919D4598FEC003B6D9A8 +A0BC7D456047A1C0579453FC1D7CB2D158D466939A23D7A7B8ABED7E2777EC7487973E73F2266D9C +250CE30729E3C5223AD93B9AE8443B35711E446A3DC660123ED45CE1942A1A2AD0610467E081CE2C +8B92A6C82F0B17B5D2429E99F1A6268072C6B5AAAA6EB6283A872C54D3694CD825EB2926E57DBBC7 +C1663075E687A144E4D61C225781D80FCAE1497B442342B4A3F1CD6BDB50E31791CC3928C30835FE +F845B6BE5E2D7E3F2F5F085AA3FAEB45CAD0D76BCBB1ED859A9CEBB9F7457036F0BC3F195CB1A98C +9C8648F6583CDBB23894BC719D68C2DBD8003B10D08C8CAA40BCE784D7BFB4EEC9EA5359AC056E57 +B8B0F2EBCB1F4CE40C87FC7861180133E0CB6CE2FC4FE690756D327A2B5AE063E3021C0C0BD420D0 +56F0B941E6B36088A55BA11D0C35FD0132D5F48E5D9673572347171B4328D4807B972831C0D74CFF +A5638C145B89C989E6EC942148207D6DB82257585958034D9F9D4221C7C9F7013790DBD130F277E0 +BC88BB179DD09E27062379ED06F25EEA8B7FB33C35861A0034776E3813D2E9E5C10E227CC569AB36 +CB2D9DF2E7B7B44758F9DC4FFAD7A24AC7E9F47AA850C221048C3CB35A37CE8EA75632AE65FE3212 +175146FECD6334AE3D3C5F492F067F795E1E8FF386BA198CB74F0BB4DC0000DA383BC4CC3F070DE1 +7721431988D69C8B1A5AFDCCC83C22E16A87E01C6D3E79DC7AFA3DB0371B0866EFB8B6F88900472A +FEF1C4A878243C52D4E02E82658979731C841C489A6B97E271C4C93800EC7D91F93EB9B9C659A554 +E1FCE42A5EC65AC39190EF4B66DEAF6FC0569A000A9E1495F42F706FBEA4D32EB7EF11A648910259 +6A65CF899C2F322F5679C6D123469192A9BF1A7F1F2C81C554ADB97BD19ADB746A4F81A4D5559E60 +AB94C483DBABF6CE2F28CDB412D50FF3FCFA3B3DAAACC6A83CFED910CCB3B8D2C19590AFF4D75303 +4A6CE7F4156896A13808E0DFEAC547E69D3C886691728E4A35ACD575B40D721E8FCC5385A2EB28D7 +08101DC50811529528F5CB0C009BA7E3C88468E37768FB0D83895AB54DB2DD5426562AF9D8AF304B +F6EDA54E9C92643DF926F5C3578269750120302A37CB140A18BA56BA01108D4ACACE8FEAE640A6C6 +958EF156B588ADB0EA5F3B0F37BBA12B7BCB221C811415387B024B7076FA4403A3AD6EBB5D9C26EF +EBDB7ADE7C60B444AB9F90EA493B658B7767AE2BE649BDBB3FE85F460F1ED137C61BD95F7CD3D8B0 +15CE45138538930AB62AA0E54B4CE1A5EC5FEC0A2B28B345B67089A4E4AE14D2E1F5A9C8848DA688 +CA298F93860649EC3AAFEF3E820D86988C8E3E5A4D4BB937791827994AA3E81D0BB3EE115EC36D5F +B9A392D09E79AF514D11C7B3A03C9F9C13355CE79E119A19177FFDCA34704D38118A8976D1EE5AA0 +2D14FEB1414419F5E85244ADC5C0A765A522EEF36170064BB19FEE3B5F7B441E4DB967DAE0BAC2C4 +8FC6A836E0EF5A69F073BEE1699F55E9C757EBD6FD8B514E2B49D6333815B7DBD1E0694695FCA3D2 +1320A0C4B852D9706DADD8369A95FDD917328BE93DD33818954DBD2C212D2CA81560ED5BC284EB04 +7A5F389E24E43F4FA8C97FECF46589FA7341076555CF55B1C21B28E0C1CBB00AB8B6F67472F27BC0 +D11148F407824B0159B5188D4BB7386FBDBF1C0FAF34721B7BCB5C0FCB7C4010DCB6A1284E9D7883 +9E3C2111A05D29AB7997073B590A81C6168020F1D48951BC7D8476D5BA593F4F23CAC1F9BB0E091E +84B4E99E5C584D1370DD12DEE8DF16AF8BC6B7B23E2FEABDB7F32779AF8E2B5094A6E9B7A7225F24 +C43A8E5D2B977E1E19E633C26771E23017ED233DBB02C64F8CF03992C6484528D0C8464B46F24F9E +8380F385D5D01B8893C67FC103498983CF939432AA380CA576D09030CD52FD99BDC3BE16C7204CDC +3365BF76294A83A1FC14A236F5FE5321904E779B13232A76F8FE521F425562678436359C2461BEA5 +AB27209541F557AE2AA60009C9CA0A9FC7898C14306CE35A50017BADEFDECBBF94EE2905220706DC +806409EF87DB1D73EAB0698AD2DB72CDCDB293E7FB13C94D9FC87E74502E6927A212F0D7D2F2D194 +64F7A66AC07872E18CB1DDE8F11835DCBC5C4EF039333FFFC0FC1456DAADE7DAE3EC2EE0D3415B0C +ABB69FC5006F4D14A4EE1A5CA99AD4D5E629C0DD1E0F097B5B93DE2DD001A8C418234C9C45E8C13D +1AE04E9466DAB8CF1ECB88A4E059C111A6468D2DABB90DA79C7C79E94DB28F6968B1A632F8C57D9E +565FF91C6916026FFAC0661856B9FB8DE9C81661816221B1FC159CFEF1751E7E403F5F2CE32529DD +540792FC17A12A3DCD7C50D38EEAADBD10ADBF5D8A82442AA900CE6150EB7A4639DD9FB6E385B2FD +093493DCCD9014B23EB172E21AA89643A6CAD1093343D85D81261972DE0ACB16A4C6B5F0BE4C978B +FA12D3CAF0134F9EA49F6E9687C8F99A456745EA252F0BA9968C7F9586E3DD841AA92DC7705BDD68 +2DAE41518A09DF0E209F321D7FA3417202F4BA76A984DA3ADDBC58136885362F02F0A24EBC439B3D +BBDACFFD8498EBD29F88F016B1FEABC10785438EAC860B554525F3266097A675299AA0967BD3B7A0 +EEEE3FC578D1BE99D3533BD91571AED904BFC9DA1A1451FDC5406E1CD614E0C7FBC733563CD6CE6C +C31E9237CA153F1F0411114361D731636BCF98555ABF12848AD109371A42B63675A4130B81E97C2A +2EE2BB5D8FAE2640156001AF0F55D9D5DF8FF23C8AEFE14F120000F14149A36E5C94CD9081DEC277 +C2C34870D05011F99D48B0875A5FF542F067F7E9880109F586BCF2B50522A1F23ECE44349E539E70 +F84E207DC9BEC7CDF856A046F1A03226AA41F541719AD1AF88FF211E57DD0C1275DD0B7B47440DA0 +89B98C6EE92A7D94700B83CEBE19EAEDD8A615F6587587BA8BBA3CE3AA5E8EAFB1FB0F486BE3609B +169EFB178A4292F4C0378AFE5D24EED1CAAB514DDC66C696D8E37F294A6579131DDF5488E9436609 +ACD750C3DB0A940C84FE022B22ADC2676F62E91E8F891225F891FBA537679B24547BBBF35F04915D +20B11739F620D18B5B216921D222F15044368569AA302980B9225BB839F494588481B94B0C724352 +B2DF600A22B062561D86CB8F81514FBDAA4F8A043A0265F992FAB71FC9124A45B8475E1EF3DF6B6D +E35CF329777D45F08325E8505EC0D979F542807AE77E57E453525F23BC59A50740371EFA98678AEE +6C425374AEB745B99DDB5D8D908FDB551FBC0DB15832107BBECC4E11A1A8DEC69358A574A2ED46CC +31D564549EFF23102D92BFDCBB2BB985F78F36033E34F59C0EBAFA3BDD71338736464CEFDBA91398 +33995EDA4207BFD4A9867D32E867FBEB7DE60D132803EF9347CB17BD91315484EF6570892297DD8B +7D966103339535E28A00CB1EECA4A9775F60A9F5FC9BD8B06D78FE8E6318C31DA2E847E3F9CA587C +B01AE2BA0A2EBDE308314413F4F230A758184ED60D4F71F6CEC22A93A01B6C54E0449A3860FCA895 +4A347B7588329A80974ECBECDA1070FBC055666375229F13DD995E99265DF870BC8B8CC6347FADBC +1A6AF64599271A475B9123493D46BEC41289BEEB67EB97A8DED7A9C9730D37C65164CFBDC22E5CA5 +89D2E7954C7136EF4E084C43A6C7F361A3E96989239BDDB9A593CC2A80BA16DE9EE90E95CD39393C +212AB22EECB677FD36D34DEB46C4AD0D21BF7E6D7CBD0C8083842FCD87B18FEA7CECF939987E99BA +34C214E44DD84C176C9CC5A4CEA76D380CB316BB4EF9DE73D73B4AFD4ADB54451591DEF86621D138 +D5A0A29441502BF6C2ADE671CEC3CB5CAB903A657EB2D70C943F976C110E46C5D9D29BC00A875F27 +38E5D22496A43E096E009C5D3CB724B4CABB32838DBE527F83B18CB457E57B092C302EE557FD4F00 +DB9C56E66C9FDF4EC9FFAAB85F60D02BA79694FABA476A199A0331C30A78A92E10417BA236E23364 +8174C826331DC1BAB87C5F95027846130C6A2B4027930EBF9A97BA1B039D386FC51C302648E25980 +212F6A582CDE2778C677A01FBFB3C5D1B8A374ADAF6ADBF7DC94075F25ED66D440B3922C5F255FB2 +3FD8F6E21EA65B1D93BB225684B50F11310E242B087575973345B229BA62C1E2C35BDAEC04D10148 +F5B2F3BCF7399BDFDF1F3F79119714AEA697245BC647316EA157484ECB951BE367234FD02E8B1F09 +1AAC3D29BF282DFF4011BC0CBA8E55234D943DB3017CC7A766720BBC29B2D097A956C0F1067177F0 +12D42ADCB473CDE8D1BA35B4030757FA1D8211989DF3BD22CE5D501C21EF8708FB3449DF47D88650 +9FF7B59B76C0DBAE443F336FEE2D615D7EED1C284F14335BC8A26BF4621E10DE9611FB2F1DBD52E4 +B7565D8C65B54EA36D508BCF0C578A49A2665227CDE1F9768EFE847F9D94F1BBB7DB83701C232198 +5C7283D47B2E40B27A268428AAEFE75F6B2F8764A8494E5827573758CB9CA46FA93208836BCCC8B5 +564A69F5AD882052AF1C1417C3FA7F580569528682C77080F3688B65E7FC24D2A3AEB61574B4A321 +5927281544DDD7A6EE0A3E9388F8F631CE7251724DF70726E5912DDCCC8C652DD6C9608F8462303D +867F589DE0F2F71711B35142EE6EF93B64D6326C4DD7DC83278E057100EE772082E6BA368ED91A55 +53ECFE2293A481E42F83BC8F9148C70EACE91F7B7D9CB8A72415BDB3AF66F68EA733A17ABE9DB005 +3BF148629132969589F38D30EABFA96A01FAC72650B5A6FF3935670198A1EA33810A9B11E330EB8B +451F24F93544263436F669AB5A90A53B16CCEEAC36B1445574EFA7E802DE73522BE725E68704822C +B7D3912717333367895BBFBE06966A5CC653AAB5E9B3596702086BF0010085B900711932A95ACF15 +CA4DC45A754EA334E9EB84D6FC8E3FC4F897456BED64BB93B593549FF0D5352275D8E417172A6664 +C5E0ECED1019494A7ED49AB0B965BEC1A82E5873766BB38D7D856049CCE2FCA65AAF61E961B60634 +E2A69EF059754C9D8163D87F928C222772D070D83FEC6FA5AC734AF65E40BFDE521F7D9CB1650FDF +64754BFF21EA3FF0AF7611A93D525EC9B28C51AFECB04E7FC8323DD6C9B0D8539A34FC3CD8CEB795 +8E8EBBFED4313C77ED469C199552A9FF70BA5423B03B6148D4EAAE17B71C5B39DC436AC53D6BA8A7 +AD81AA8B02335A8B2B11E9F4FA913159A725B8AB60F52F1A2EA50EAF4D56656E615BF382CC68A690 +BF83DFF24FE986570ADC0290ED1A37C1C2AD469CE789E0EA0BB5CE01020100E729721AF3B5BADD33 +A2DAA6C33EB8F9064F5292F715F820B4BBFDD56F76D42E7A1A068C1CBDCE4640082F6E7D582D1939 +990CE6EE8D270015A2C461798B37DCB5798EE9F7512168B76D26C28BE4A49A1BF96C89D235F21A1D +B6A96E5DA474D0B19B808D13D7A11BF39EA8647499C410ED9894A1ADF33D41B6FC2E614D8087F4C8 +4E437B136F3CB32DB8393C49177A0675A0C9E7EECEF448A97AFDBE840FA01FC7E5F2E8FECEDC1884 +84C312E8635CD79195475DDBFDD4D38D5A0246DE2C7F21608F8D2C0DA1371D302E941572E5792A3C +F4E51A33228B93A814D03FD4FC223C314CF3714BB3A34BD4F7ED6348577FEED9DEB082C4049E57B5 +D3CDB7F26629E9F3BA36893E09E3C7463D02A22D7056BE76B87763260E46E48BB832B7EE13F8DC05 +37EC8E81E9BDFEAD8C27EBDF1AD706933EFD11131E12814F236EBB01BE85B7F1B2D627413B324918 +D247604F56EC128909873FEC3857028BEF76A3494364C2A7002D104D486236C30B48E2B75D851C34 +EA50BA7FFEB4E19190898AE21768C157C0CAC628A2181A32796FBC1A7271D2473CD88E5395DDBDB1 +FC3AA8DF0F3D588637F19A8B833AFDEB5F655A8838EECD684E2315B72C75CEEFBCEF94344ACE8D6A +DBE355008EC72FE7CEEAB01363A895F4E73F867639BE0A0BE67333848816B05B419221BE8F9066C3 +62C23FE85B7F392930BFE4C12B9526FF2FDEC38F23A159ED61A0718E7115C24597D849FA76369153 +54A40C965D4D72EC94DA61A03766AB39AAB684E134FD1407A5B1B19BFEBA52AA0DA5D99CBE5C82DB +AA663711E6DEBA180E1D4A39C320516A4350D296BC19BF1BE054859A0889C7E9727A021F3176FE62 +0FB0C837E4141FECE531A950C03D319E3255703220B7185BD20FE5DBA673F8129AB211EFCF36EE39 +4C7E00EB0876624BC840FA86E58B2F584754CB6BFDFD76810E300741EBE4544E5AC17413ADEB21C6 +2F66CA4F075C32381796BA709782DE34A675B717A2C7F6D88104CB924FDE5DF775B4F0B68E0E2E5C +2F788BBDEAF06D8E1FC2105CCBBD5827C0B03FD6CD64F0D073F3192D5F94839644E5EC6C5185BADC +F04112A65F49A8C83174A9AE958E76A2F5AF469E8B76C833782C5FFB8BD7B1BBBB3EA0CB7C9786C3 +BE2ADE5E7AFA8C8F20892659A59BC421E28845A108E34EE17864042EF587A6D67DECDFB3F510EB40 +D2229585347A0035670FCC76C2837A4E4D68304FE113C539B35C1F0234B5079B8E32934546982978 +C5E4DF955A454EA263C3CA5D7101F31A318D82A3F9FCB5A8AFD7A65209663B0FC9DA400B26F285EF +46D0E1EAF8ACB1F1CB805E3986D04BC585073FC64895E4DAE1CCB749BB439CB32EA91176D5C39C36 +50D10AFB9C9884D5FB90183424CEE67EF2175D01D2478D67511EC9F54F88763C152697B06D948BED +49240096EEE3D06AB4575E8E8B2CB8263B5BCF4FA1608720F52B675309833071879DF52C3EC2871D +20F398B5CAC8F8A4D41D0F1D47584DD90DCDAEA4A1CF160C4B3BF1AAB890B5CEB6CB3488672AA68F +BD938281DBC1D8BCFE92FBF514DA5358443CB6E0147254E91B38CE6787B2BB0DEDD2D38F5938737A +977B5EA42892520C58F8FBB53C994B57382379E9490F0D6970B980E1BDF8CF9F4C3C5E0A18F66E86 +EE93FFE7FE546DE50F41364BCB3721B637072571FA1779F1D672FAD260C16D7F13CBDF3E4376E7FF +56D2A710AC5AC35FCBDBCE2C9C17E523BBE6218617B13C1FA6679B308979AE7C61DA6E68369324C6 +CBC7DDEC364E5A86707266C0B459EE7B2C03FE584E529BFFDCE98C90A2F3D9305AA74D3ED8430DBF +3A49FE2ECFD9C4BC9FEFD22618FE9C8A973AD072AB6F713E4DF02DCDA7AC5359B2D652013E131B76 +B3ED6C75FD53BA58D862846264627F6B9E70D8800F6D9B32242B747A67BB2B45675840D34F852AA8 +062FA6B01E31ED24DAE02F6CF788A17F7B9368175195DB0072259CCE0FFB2C1035C1D26E1777CCA3 +D56A827C3242069E76D6DD69B653768614B9ACFF16567FEA61508D51454BC02F6C60F755AEF6AFAE +3536BBFA1823F8E1A53C41124DE983E51CEC92AEF4F99785D554488A51C20885346D1F761DA79017 +940A0C557D93F1DB6B3D00FFD61D08E96FF3AFCE5FEDF545CC9F47A2B1BB26713431D6D1E47FD6BD +6E3C668B0368241F0EBB5FA9C991DF79890E52E83A3675EE699B61BAF869DE91F67278F510061C6F +E41DE2D883F48CD0E068E2A652B244128D82E5CD52F35F210DDAE3054691ED55A7D99088AAE8FB04 +F525C2084AC09F5EDF80A4EFAFE981F74C0DE9D194320709B3464F3FF2C0F6AAEA6D973D9C323F53 +DE3D741F698FBF01036716BBD62957CB32CD81D3A2674560FFBC5BDC5C6E4F547E589AD0B1CFE14F +5E17FED1C4A8ABE4E67CCF8A49F32C4C6044F1431E1CC382E7758722A6D0DF9ED23E51F8AD14D11D +7B6428E27443715EBA4E9C05D6F238378F9498AEF0E7EE4FE6856622CC8E6ED141EE5F109E343CB6 +695C4BE1E0F66601C27975983BF557C04ACFC19227A1AD7E6C44C00529FC7EDD7F886D24B7E029B9 +C395260088BBFB96972199A7B32796D27257DE83A7402291C14FECDF7998C5C96B1EDADE0280F856 +8A8F5007852EED303969180B3329917973C2D32C080C9765B6BAB0673BC7ECFDBBFBEA980C263843 +39B7F1052591D91667D4FEE413AFC23DE2D4B9DA742F4269C6C939F5FC32A38040730A018155AD73 +3F231E4D5B9D01C03A58EAE7B5F590CCFAF25EDC8552CFC8D95C60EBAE1837D7A97CA137E9D4A4BD +2CD34AEFD68D64B3F4F62326AC429921D7FB3C235184FE0899690A0B775F1A566EC29D5830D32372 +6526F7E7F5AFDD71B77E07613DDC4FC63EDF49051AEB59E6337AC0A4B6DD872E776C9CD0CCB86130 +5322D816732124F5978A86C186BF0A0F88E733CE38E4D7C1BA5378C5629B1EFC97806059990ED42C +5CD183BAD7E94070E4058569DA2E51831FFE0D080301AEAB4350BA290318AEC582C78D05DD92E5AF +B4424EA808629BC972E68F4FF2489C245593F07555CA6A2B25964794CF31CBD3AE5C229AB9B8C298 +06C01D116EBD0FF0F159ED2D3D7DFC73EAB4910BFF5B0B0B587CD9EA6E6FC45D63C09766224D8346 +1F0588140B258B1729F70BAE7962189B1554483392988CF230AF4077193E53330519394DD99BA135 +6D4730AB221DC6A66019BFAE564893DDAD7B177DADD16ADD21D396CFA6C3DC818052E2F71149FD59 +4A16DE0C2FFDD366C99B486C55A6E991E4D22CCB15843F0C3363676AF2F5B2D1B7EF66CCF2F12DC5 +0D63776BFFB058D70A9C76DCE96C754872D72C82A0C33F90D49C935402CDD26B6D743B1F43BED5D8 +B539424849C1495DAE73044E885A7D0F307F1816DF6244A6F2D97BFD4E200E93F69B08AF39EA21E6 +E347A47CEEBF803F73B978ADBFCF056789BB8E6E2563DE87DD9A8C877157B934102DCEDAC54D487A +1BB2694F0034093C48F10A17D32E2BDD0C723CAF59ADDD1BE373AF8C9BEB4415AA5AF36310C31F24 +354A53C0B962573148BEF91D994FE3F3D8450DD4D686725799F53C373A0A3E3C060C2E1A3E800504 +9F26D716E1F381B9F83125E4683264A07E2D8938F605978E2513DD2050B3D8A1012797CBA8961632 +BED260916338A812AE751C7B657E086A0C7DDCD3BFDDFF3E48B84751925736D1310C4910FC114387 +F3ED7FE163F91895EBF55FCB425CEF5729D99BD8F2C072E36C310523E75CD8E5DE49C031C4263410 +9D56E91A46C8C8E89FD92012A00C33D0DEC52597B5C6933291A7BDC5CEDA95DCDA5600F9AE1C8250 +54E7EE1067458CCB66610704C58E4A4FC0CB5FC933D0322A716B2CD430A3AD48DAB3D4CBE9D23F2D +092368CFC4E1F5495C133A92942EC62118D45C17723646E69407B4A89DCDFD2AB3FFC099A21D9D29 +741D68270629AA3A414FE58658DC9170C247B6E23F35C4BC5FF83009F462F2EEF4DBAC5FD158A658 +57F9B6DC1F5192DFB169DCB65621CAB2F1B07BD22F4155A8E9E2B6388D430FDE5EC1C834D22EA035 +C52E1E34482EADC36B4CAE902AAE89A7284E62B3C84B608D6BD05F75BC31310B2DD3B2C08A00E073 +7F104F03A41989D5F6B9A2C38B22F1D1803EE5D7A4D8DE44E4ABD496A1DE0C0E12C4BC96D0122846 +3F0EA9CE9509FEE987139F3DD3F9D0DF4313F555BE85433718F6D05F197C41A9D9C7A8B0D2740196 +82D49F58DD5F66B12A6520D9F226D1DF1F1B65CDFA261F980CA25A92645B86B64606293F8BFDE364 +C47D2AF2C709BBE77A70A5712F2CC26F3D66F5BE2C307A48E6F887F681D30121E32BBD87271B5DC4 +615D28C309F15AD263FB37424E56DDA6E17B998B45BE6C7FC6C28E3394A8764C9EB2DF5C06626593 +B5C665D550D4600172791CD208AE9F37BC082B0B242B0A504B751B18F4D7495172B697EE217834A8 +A4FB7CC16D6F9E8BB400BE8AEB0850960283DCE725249FCC4DE97D9886745AB6066C3E2F64DD8AB7 +9AA11667F11188D7965DC11EB760B772E282DBF13249F31986AC6898FEBFE23E3E8B8D2C33E00EA6 +FC493850ECB2E6D831D1EFCA3C2EC8EE2E394599091ED58BEDE97D7A43B6F739EB0F845EAC1DF6B1 +EBFE876009CC5D804B15ED4B56761B3CE1AF59C07B49DC798A44532297AD73D5101ED47F36A3678F +818297CC27F6AAA2AACCC9AA9B6F5459911D8C56CF499E390AE607F3790450B2B9C9BE0F006EDA0C +715B5CA0481734CFB0597478E7602B0D2C1E4F78F03C68C17C70E4B42D7D2D3C95CF40F73488B371 +8E2CB05A549944D86944D78724E266C3319AF89AE430E777E95F0D792B1C654306E421F3D63A26B2 +1E74B6E8B21B2E2B9DC596D013CDA16D08E65E8F24A84B12B2BADC653E6E1110DE2E709C1C1BED13 +707B70A421B384F20CA7A9A9D20324DD383F28B2D3C7A9C53F5D4C6B7C378D26DF11CF55238BE1B2 +4FA70DCC178DAD3D35670FE4919085EB1CD905971D76A368FDFCF9D2F0A23739851A3A6D2E02D65D +54DEE69ED5D81315D3EA5E356F94EF256DD267FD1E1A9EDC9CD63E743F299BCC4A4506233B8DD765 +2CA067F741603F93250C087D368F9E9CC4CC1A6DED567487C05BAA992B0056A77F630A72008E3946 +15A9DB24FE56A956650EC9DE90A6C2259189440247970541CA198748928215C0E132A81AA13208D8 +63C1FE817F70CA573B54577D10B73100AF8EA088208A44FB92ACA314AE5879706180788C17BB1D0B +81B6B95A1C4E0F9EA66F9B39BFE12444A6446691A7BDB03E0F03D9F07A10A7598F2166F108529F34 +CD90E601FFED3479ABCFCBDE8F051C348E48C61D95B00C59EA1287423F05666C3D36288844067E83 +E14F6B5210842C742B89F13ACD126B9FC50ABE2CA7D7ED513D43B6AC7F41EEDA416BFFFCC5C844AB +2D23D4DC09B2D510504CE98D02E72020D9E669DDAA344C63A1B75632F912A1C0DA3885DA4AF7E243 +E4A4C6493D6595BB6D56B0359106957259E59E336BAAF35BD1CEC5CDE735272EBCCAE8D4904AEBD2 +B32610C6FEA2B69941D6542ECB44D71092A3CF067708A3D087AE99FF29671AB7DD8758759B971A08 +AE1BAD78270D2FBEE37AA2DCB119D72F6C7B0C8509018A70D0B0BE2C6830EF8E0B24B1CE1141EF87 +3A4D7DCC501F808BFD94E4DC0F2915AA023076BCC8006490A43685EA25AAFC187302EBDE7FE1965A +04A5A398985D29F08E085127B56B057334D88EB638A4DDE64AFD204974C3939536B1B66A54B4DB81 +151853915718F70813F096CC1B0EA25E363B49264C2AD17158A4489F91453FBEDBDE15D7B74D7F98 +E81DF23251785D58295BA297F295AA6248A912CDD4F1111E6B628EECBB5139709E76EA4AB743CEC8 +26621D08E6BC64691CC90B3C3C1778931A28D3D5B1E20E96C643316613FC487C9B604C43463FA453 +3BCA1236286E6F5A6EEB2F1D9C34BDDE4595495A365F88055D9268541CF1654ACF478D384A5496A8 +772EA1402751A093582A6625A0A44816B5FDBE166835D598644296249B92CC90AA3FD6445C9A19BF +27F59CB0616C7306070F33C7DF4E1DE64AC8C5BB2FFAC1EF2B1B30E5A0275E6004CF64BBE2C6710E +DCFC3AA4ADD60106334708862FFA6652825BC84842736E47AE6917180365C75B27505EED3C6108E9 +898A780E20C3F606A860229AC46D0471ACA0187D6D539A1B8820F620F72B41AD1D3BF3834BF48CA2 +AFEA8BF535AF74C4562DEADCB63D2F5C7585722B77C989342D190FF926C8A5263B4F25286F99CF6F +C62EE6E2AD61C82B29D82468AC10FD27764278E5558CE8B41BA111CB2F040914451A480C93084237 +CAC8F66BB7C6689F340B8ABF0150E06D5B1177278A4C08742FE22F42C28680F190900344ADFA486D +59718C25D37275BCE4DF981AAC35D2C7E85C72A0188B8953CFA516FD545AEE0BF4B8BA301CFDE214 +4241FBDF3D204E3D2823301572E23F204C97305A82401660E12926EE7BA6EA1A81FF5C007933AFC7 +3266FAC4C134ED818A48E7DA01C71A46335C845F9DA5E960B25339D551582B375814148D94CFB781 +FC56093827B78578A73D4FF67B6B87F40CFA5E3F4325D9108CDB64BD06427B88C84105187316FA29 +90B4E3E8EDB6C78ABF164F4A9717D523794B2FE772A04DABBE688CCA977090979B5F47CEB90A1DBC +167D305EAB231C9F4260C4AD10889CB785169902FC0BED78DA15B8417453BB65856EA0BEA5245BA0 +573F623D215F6C0CF801851C305B355D26B52B0B343645FE25C78A3526841EDA480919A1BBE5F56F +C10ABEAA3E1FCCA7C43EE560F067F1AA2AFD642F769D1ACE8E2AAAF38850F0D757CD808C921D716E +96FBC07DA7860DFA70CEAE2888C0ED3CBF9586443532B68DAED9A926655C157A416C383A53D8F283 +2A4E67468112A09ADC837ED8EC95F70852921F50D4417239FC42EE3624CA97F682745CC5E76CC7C6 +7BD99F2180F8C0B7FB49539C8CC474C25C0DDE491671FF329E51BCFA779346D4686835A3AD6633FC +B5E0F67E0CA9CED8F215BEF4D240453EB2EDD6ADB22278AA5B985FA140C9834D38753DF2014F8C0E +E6DAD19E8FC54C03C1F6CB0F858986691D99592562CAD95FA0A5B2ABE4A8B54B457D42E8C33A2D19 +51C0419A72FB94FDA78ECD92BD2A1416459E9DECA9469F35E4C47DB531726DEE8F203D7042EDB32F +025DF3D582547BB1D45F7A5B70D317DF4EBB16E36B0D798E0932FD2A85B04FD67143E4B287A50416 +2C1F5A037CCD780088C5476385AF8168E12D97D44B0630621759173C8F1E3006B5B1C6D7138B7EEF +C3CC5F54E24B2C3CA7B41AACFD25E554880AAF406EA4C3C6E21D3B550B040FB1952598A7E8E6488F +E38288B2AEB6C4718338598A2BFE4D2B9D14C65732DA304C16FF3E1F8F03046EF095B65FD609DA87 +EC24A69278BFE65C905CD0329F6A486B8525B7EEA4F7AE56C2633CD83543269E8ACD6D71F500D82F +DFBDE7F7F7B1AEE67328549232E26CA55085B6E84D9E2E7F74068F93A90C4654F2F396E57C5F76F7 +E61CBBE523DBFBA6E76638BBA3064DA025A79E3A294FE7F1CC28A3B4C57DD6FDC48E541A85534B25 +E1BC11B4F78019457239EAEFD4BE9007D205F1D985F389DB22400B279C10948551A6B4A17FBDA0FF +C9428B18B43DC76EFB15FC2182216F1B60B4E344A03AD6C00F141EF99F89F24C819C3E32877A927D +84C2D006940F39CA8B71E5951673EA9BFD1749923219DE38929ECAA9CE43B06CFA7DA1BBEDFDA56C +61FF6C24F40E59B13870D5FDEB82D981154FAE5D6D5152DE69339359461A41A9713B6BBE47E868C9 +33CD74C75DB71D13BAE4DEC85E02FAA14EAD6C0A253B16C79514657B15E68CCFF9EE6AA385CFF9E2 +C53D9AE40F85C793E4E8FF50B2B7420F4FE69807BC5F37C3E300E6B3C3549D1D3246A2E70F091054 +1135BDF805E0A698E236B6496702D061241687B7B8D1A0E517DF0476DA09D89667A7AB375FD2672D +CBAB8124E511502DDBD08BA04D941DF1CEBDCCF7ED48405CBCC33774A68C5212FC6F132641FF413C +984F8B43BDFD7B1A2A3435F15AF07EF4970D3E4A0BB947C181E9CA27CC14A35BD1BD096875B45873 +8CA244F88C28728B74E25CB8C4FC1095A56CA75E4569AD3082EF194ADD11350DB3B74B96761D4538 +596FF7243B1E1B724716A144106E080D42036444FD472998460CE9ABBD05B42AF9389AC452BDBBA3 +A13A96890025789F16B9D92251FD3B3BEB2C61EDDB370A20456E3BFE5F4039E2557C451C524F8087 +015BAF3FF05F51869FB97512968BDB2B49589C1C7AF1E085250A47657465F480B7023E24C76731AC +0EAB6704123D77977D3A2C4C56B691346EBE589C619C04515D34F81FC6A17527D5D8319013C5D4FF +27CC3925E24C99231AC7FB9EAF0BBA482D3B75807AC85D03CD09DE5D9AE0B07B7A813F0449786500 +0AE8A7E00080300F0AB8C399057EDDBA273DD2E1B2A0DCEFAD3B332E6D4AC1FFAD846167DFD70E03 +46DAF84AF292D4F424256ED5AC4E104F80697050D50844A708EAC9E7F7784FD01646F3BD0C595CA5 +1EE6BD607D254E78ADDC5E15C3B6AC4940EC865A5C23105B6BE09EA09F2C05D6D76960A843B81EE4 +33977FAAC3CBDA85CDD2F4DB7C28293A77825635992AF8F3B38B4480D9A139B1662345A8ABE1634A +77496C3F57597D2985E9E54717AB2E99CA35789441BCDDEDE9A9E2106B401D9684ADBEFE40D607F0 +75C179E9CC03E59E65430DB70B441D43DF03F2AA6FF06F224B6E455B01C64FB89EEC9103E48453A9 +749B4D602808C7E408A8903091D85E06AAF635D0D529C3CDD1B8479AC0F4208C284BB678A547F2BD +77BB17C86D4560434F7AD1937760A6AA55B614CFA9FF8C9C96561AE6C8F2121C4E20237428BC51DF +2099B6C49E3EFA18E6D439E6E6981E746EBB1DC461259D8EA0F8099C47CCA27B2D982B72C9A07CF2 +1B3C05D6E26E6E286E348B8944078E24809F9C5F3D014B4CBA02533F5621BFBA1F0EDB776C634746 +703C9F73BA89B1960A496420C68F54E5B901A6D733D7ACC79F275FFFB253F389AA480084468BB34D +A1E797E43B7F6E8CAF5E8C93069A3A2730E57EC39B677BB73E3F07C2055599F7062E53B37A5F0099 +907D2ED87FF7A82C95FBAEB888033BDFD67BA3A6031A4CDC56CB1E4CF5B06B46E16D988BECCEFACB +9E1C037023D7BF5CCF5D65AA66A17AB361BE7981F132A578F3ABFB97960A6034F052D9D5AFDC0679 +782EC90F240F943A5F9A3D969ED7399254FF67D89DF668F7C56FCEA1FFDCF20481474AC8495D3AF4 +B6D7EE093E369C057F0B70858220693B398ACF8E8143558132E4391405E30A73937C53402E459F4A +A3539CF7A99A3F51C0307D045DF8B77757E92EA2F51BF0BB4F77D3904DD355665870C2B59F1ED7F8 +4FC71FDD7F0B6C5D3182DB77827CA6A2060D2B8C83C4EA4A432EF43A4D0A952CC6CBBE52A9F0CD66 +1A538973DE41FFE9C5CF55F2506B9EFEE51FBAE5E63BDCF5528499A47C031163C88D3022606784DE +2F46A9C9235AEE3D4F71D4959B0CFDC5B7E78C8C0A8F9DC99440C2263DBACB343C5C648577F5610B +50EAB1CF7FD02419EF3941C7CA0B0E64EBAD4B2CB05A0793DBC38F1946D44767BD287F5E9779C611 +CA0DAAA1E7393DBE0683C8D3455CDFEBC0E64B54B737E298DDA605227C0C4BBA87AA3EC7FA6EBAEC +39E6EF2537D5974391D31739D9FC42983D81AEE44711C823F35F8E2321AC74943871739D2DBE9748 +FE68592263E7713F27E0D49B9B5CB7A4E55DE54E6B800D15856450FFD3AE5F287B12AE4F438B20AE +9E27E6CAA00F3EAEADBE08432684FDF9931E925544A680182602A3C1997DE5D0630BD5A010535E66 +E1C123013D23966B3545C7431C39B97295BFA4099D14461004C42C85095EEACB9B47C593BC6DB863 +533A8619BAE09095DE8ECA432D4DDD49AA600D277E75DC3F5C6631E2A05382CB007825FADB77438D +CFA78E252D79B6A196D5164C2FEB85D75ECA25FF80B1D97FE10E87960CA0FC47C41D3A213BF141B4 +8BC3AAA93FA86245064668394665BFD52D12C3BE4CE39EFD8111754398A944C3FD1AFA98EC337BAA +AF899D35E804CF416AD7FE45FFF13FC6354007501043F98FE8428DE8013901BA6A28711A2CA85A27 +0BB135B72F1D5026E8217581860729E94F2F1878A0E96C59E9F62714FB5F8F25003DFC7347E99007 +8A9A331CB3A6A535BC61866F02513DEB982C4A13ADBFBAC3FF70A7335F40D5489E48E5EDEDEF1619 +1973D932479C62183B0E25EE8C4F76D4F1AE45DAEA4A12AEDD9EF81D248E8D19F8C8A5BECDD1EA1E +98783EB7A38149170851B1942C96C53DE06DEF80913BFC04E539EC67C110498D15B78268853E5C72 +F485F8A27B768569E54241F6115875E2973292CF48FF91D45EBED627AE9F0766D22201B20AFDD40E +5B17CF337F2999E0BD15B86E46EB3C18FC12B7DCADCF9DD50C6C7E3F37E615A892DB3F57E250A072 +A49F7277DD6A2C8042698233D35A699B17ECA5DBDA6D250ED4A16FCC893BF0DC2E33FB1EBD7DEDEA +3C1C39603C8B7E1A5A833A8FCDD5570BD088749BB232615366687962C7E56ED089CD7B092505CAFA +5A80F503C4CF337F07ADF0D106937E25670839D491F7BFF7A523DB609D126328C16113ECBCBF9C40 +04904427A108618AE5D4ED809F8CCAF72251104C94EC5BEE21F91B179D31DBA79CEEE5EC7FF698EB +84AB1D2D1A624F58B3622A78844CE51498B2CEF38EAFE259D22C7BA61104651A862008BC1DDDA58C +C45F663EB26428DAA85E7785363A69D2790996EF5D9621D53042F42F794962FEA46E46F37B8AD1FB +76FC8D5CF2146843F8CC625139C75FB42DDA71A752BAC48F294E4C0C8289FC46DA5EFD9C91BDA6D0 +27518B7E81E8B21F755A9615627D5812ACA674D1527A1185EED4E3C628196E7D0759B1CAE6B9B7E9 +01E9599A65230F1EE469CD33B9BD9C104C44E3C1AB966C9678BD0AD78111A4E0F2D07A01A038CEDE +7036D0534D684A1562A17AD64A00F279200C0371B1CBA61747671D2A21D3F9646CA290F6B82418A9 +6FA177C6278277504B7FBA936325F5FA124AB018A15DC18D2C5E8F93CDEEA52BEEDB78A57828D81A +3E6C38B9FAF3DC4EB7273ECE3EA4482A1C6242A335862C2C3717F9C9ED95F77B140C4E1569B2192F +C7DCF702D0BC9A50428EC406F8BD0CAF886B4D979320D3E429816D88F7C7146D960AC12E70F2CB7A +9F4E3E366665AB3F1B4B6440F55EEA26DC9EE0096BB7763731740A537766490C8C174723BF0EB40C +53701AAD12B21D436ADCE22203C1053A9DC4E9F17AE617888C4B4E6F3A720E4E6366BA628221A387 +D8AB15E04AD69387C310D3528BD2FAA5B22BFF3FA494F5FBFAC4F771C9C7402B95580C5AC4BB3AF6 +92A70CB2C851FA5CF1173EEC3EC29B5A05A0B728BBBB51D3B7AD8B0AF17A1563E82FAFD93F8B7118 +1FB7AFE352874F4EC6D334AB6747519AB8E847B7BCED33EB5458A828E074E74BA621BDCD03FEA604 +7F7B6ABDA01FC7514BA1AFF0D4D0C0CB8F4E42D5A87E395D9ACDD02CCC220C157153422018725846 +009A3ACD8C8CDDB66BC6836B4026FD9F526AA275D06C813179E5924F26A25094E7BDA8BD26AFC4CE +B41D8964D4FC4AF1DFB0595BC5D6714C32F15DC7194E9A3A73013C45D8FA55CC0550A12D9AAE8E9F +F199FA28EFC2426D8D1DEFB93A65717AF3EA8E2D5B4AA8EF0EF38E9600F7D4E7D9F1D67A2E63ECE4 +789FA74B159BFE2F91C19B0378BA52E93DF12830D99553B6618645E26126842AB70262D96E35E5E7 +50ECA0CE3458B3E51BEE2F21191136DFDBCA39BDC07939E521E4F492F392DEBD029C1EA237BD89AF +76BC89F618D530160AB16269FA6B693CF14BDC4EC7C630025703C5337F61458FA09104EB15C7CB20 +AA4C9BDB7CEF3A09F25BC7F3149951A7CD75372993B80CD2112F7674CEFD6AFA764AA3486730D2C1 +897A264D82A91709FEC4A21E30D812F558451804EE6F3DEE2C4C437846BCBDA07C5B6CBA1D94AF02 +9163B7383CAC6E088AB1DC14ED3743EE77E26EA7AD3119A76C0B5F925C4DE305CD7BB3A09A453947 +5B9BD79BE28FC462D8718CE05F9D94CAF3387BA55E6E447BF81A9EDDD3A34E17BE66BC52B0C0BB6F +86F6F008829173816D205182ED2ECED319864A796AB65D4E3950288BADA94FA32B6F453AFDFC6C39 +A4FCFE60353A64627E2057D4B379D3240012B3BB0ED0C7876CB83C1BA5EFB6E2A03F340C2B576731 +F848F762A7E1CCAF267EE06D621BC33FC245D0E1547ADC12CC0EB58B26BABDB8EAE9CBFBAB93836F +FF22BDA1831DD01B7346AD377AA298D84628BF1C07433284B0A90FC89F5AEB2651BA2CEA405D4F52 +DDC0E74B871D43F71EB4ACE0D2B401F9348EAC3A2EF0AD295036BF6CF6F870D58E00B619D50EA7DD +77BC28DEF91D805CD527DCBCFDC16C042BF9B874E3B1567EBA4C1E70744B9E7E5BD1FDA6A5FF6E10 +1613FBE58DC46CFAC1A65ADAF65E49757E9304E2AC9A91E0588600C709A61D4231730073A36D473F +518A145E141D0A5A494441B9EA99AC23F60F54F8127B477E1CE698BB4129B4B1DFEEDF10D9E665C2 +47A62F112F5CA30B0AE5DBF3E495FF06EB28EB438CE8AAAD84D5F50FB56A3AF002C23BCF66ABC270 +7AC233FC0F2723DB99D2CFE7D3B3667732A531F5DC315CE74EDB9050BF75D29E6430F57CB6778B2A +CBD57DFCEF896E6766C8FC5C9F9FBD701CD62CACF33EE0FC95E78DADD205B5F42CC63024624BAA0A +B4DD447832B4E1DBA77BDFADD223989F8E958C8D759AAA37930664C6EFEC708116248A2A7AF3D656 +DDEAFD009B7F5333854608E67E5E588A857167ADF9225CF6C641F5E19C3E08678A281199EDDAC831 +B57223B1BEEADFDCBC8F6F25D32FCA2336C808162E8F381656E847FB6CB13969572425AA05AC830C +33DE6E030F86A3A85D2A66A77F103C7042C97205526DC882EA9A00EB8BD5519847EB424C15F808A9 +1652A6CC89B66A5731126DEBADE123C63D88A2E550FACDEB3886FF98646000C64B3A91078012CA30 +904B71737CEF6BECABD43DD702880538F5A70085E6CC6015D2163681067C3D513A8C66032C34A0FE +17A58AD4BC97CA69BF41F11D5E910FDFE9729652D3EA21F8DD8CC19160A8FC77573B1E9CEF4E790A +79D8AD6723B6804E9616466C935303E063DEE29CAA6C3BAEBF278B818C2EC2F13ED645AB452397BF +00DB8B26E115026E256746CD0C78A959364FDE6DEDDCD0F441A61A1EBA32C7BC172BB09512148D1E +BAC9E791B7D51B71CAD2DC9B83B2F99B3726607D9CBE58B499A13753CE87FCDCE21C0AD0528ED0EF +B9B2C927F57C78C626248AA2B835A0791244C5896686A66173EC9F802C4C633A42B086334D2A4878 +0E53D00809247BE64E529F96AD2F8B3922A6097D414DDE1EC76F9552F9B8D58B8E34F359AD792B2B +E50C26DB05035E7497162E7C49C38D3CD9B98D620AA67492BE5AFCA3A81A7080185C7F0B5105223F +1FA77805502A2E8C5FEEA27699858D84A95842C5F2FB68686D59FE24091FCDDE139B6463BC6C7B1E +0E90D20A83651AF00C85797BB9F53ECEC1675C7EE636D0D9E77DBD8F89670F855EE4D4800FF3F695 +0EFF09BBF8A0DAF6B8242840CFA5BA73BEB95115F4A78BCC02D85ECCE0C0F2EF6F328AD1DD6CC049 +5A3315B414A4D61DA50DA46D7ACCEFF6EE56451805D26B0359AF193531F95F6589CEAD6FA041AF15 +3067F88A0A2FECD135C56682DB2B45A71D1FA737C064EE9A4F404BB72A70B3AF0330359393247EC7 +81512482579865240A23CD8479F21C2C44A119EBC4E81B308DD8AA86E60C3DD8ADA50E0DFE8308EB +1A7F201EDE8DCFDA405AEFB47E0E6CA7DDB376DCB21D37F7ACC4D3E9F26B03A8DE0E8940CA3A9E75 +963A389DF8038D2C486072F61C0CEAF500753C7A6352B1CD0338D9212B42A4D3DA23D5BDF44C27C9 +4B88A415A3242FFE2E1B332477A21D2B9CE075EE479C6E657A4D8874A8C53964229310E01ED4F3C6 +86FEF5258EDF3B464DD6FFD7F1CAF473BBE722D60FB14AB4918E93878A8AE4773930B8CEE110F476 +7F42A52D9304C55BE12846C911A10AB9B2E036BF9DFD597F5348D42233315FA80D0F563C388BC253 +2103F05E90DBF1923F229F980A2F4585C7A373511372D07DCBACA583099EA972C03E5AA67E663882 +6DB134564DB993CEEB6E7A6659C7C5C05C310267D5F8A24EEC2D5CC3E3F3C808E6D6068D1A57646B +37FABD98ECB7BAF99E7D9AC4414A491A73CA34C52F394352F6B5A15F0FC4D88622DAC694699C2464 +84ADAC3B1D366AFEDE2A2CD2042C90516A666A19A91C80248B11224BEDDF1A320E230739E755D098 +B6A67315535F4C187CFA67ED817A035056353FC859BF286317996FFFB478A2248B908FF12ABDE705 +402224A3EE5F463DD3D243875C84E02DB968ECA1CC52C75171EA50D6A88CA91327A7AA5795019F36 +C0A19C093A1C9D3723C7568F9D41F2E4FFB712FD47F897703D7A620B586B81936C84AAED61D84332 +B3BEBC4F95B796B93EF7A1F565C494F8A65EDB21E2EE18DC025522EF8E599887CA2836069CDDD889 +88E5862977B7472584303198CCE97EF9F9E1446D1F1F5ED1CFC666A8A0C3A03E1792EFB60A9B4065 +49E0DEDF6ACCDBD98742568B4735A747D8E5DE21E630125AE0C691D054E42199C15B1F80CAFA6E7B +B2005F374A9A5F9900ABB7409CCD50C3AFCCAB1214E6A856F7C7EBA89BC3291801E1343DA9DAD2C6 +ED075C8ECA1423B43E587AEC67E6145272814B3F191B3C285639F9E2D6E148A02DC2CBC0E054D629 +5CD05DBAC1950400A9189316F0265B86A732D302C5BEE8ED233768F237C62600CBAAFF3A110D5EFB +6CC7CA3B92D965CA7C5E8D3E64ECF239FE2507FC797FDBE54C1112B28D4DA44C60AB09D994C5BA78 +D663A2591934CC052BC70CD1DCA3325C66C9CB982E2039F5DB70C848D3DCEF655B1C2CD0CEC8865F +E8E1C0A267BE4F707ECE6F5A3DFCA3CC1EDF92C760439F51AA69A4C1801E96CA4D6EA4AD980258F3 +D15C893913ABCE09101984C61B91D603053E49A97CB82FBA707DAE8AF1D579FD69C8481CB7B712CB +CDDB4D287BE995E32C02B399602A08B9DD849039B5673F1930BEC7BF366EB082D2CA5DB2385C8CC4 +5BE3FC0E31820191A814EBA7C4F23B1938E6C4D800732787CD2CB97F762DFC85D4B798809B5F2254 +D826CA42B32695428D120298B44CF38494E56240B75DF1E41E46E53C44DC505452256DFEC819408D +605FF14D6C1F3F152F2FEA96EA0AB3B472D8704E06BE9F8C3E8395CAADD06D6DA033E81ADE5DC3B8 +3DAFF743C6E9E48716003D358DF63CD7FD3E2F727D1F2D0C29962F76D5C95ED44B6F08D052025A66 +5785F264A3D5F5593677B630E628B5EA81FB37CFFD7A30B7FAD226B6FDC82B0878AF4C0EC4F4243A +807B9839EA62BCBDF7C2E9B30A623876E632E084EBF4A21EDA04FC88A1C07021D0C72EC3E969D449 +FEB08E5826EC20E55B21EA71EA59F6E3B0710B0DDAB3261B4A2029ECAB68C19ADD5174E55D5E984A +4E5F38F592A302FEE6ECE732DDE841A28672C620CC5D687455A5C06FA9FE688394A04F96312ED025 +B7AA6FBCE2925F3AE559CC1886BEECDB70822E2E5CA3F732A87404B1536AAC469989E9610CFA440A +CE43875A70CA51F36CB6F629D9424C1E35A88F92D5DA3CD8CBAE6E8425A36968E21F4F30349749E0 +205BFF8D552837D6FC39532525370BBAC833F75F1854C93FC533A4AA53ADF7008173A70D94A4EBF5 +38EA9E62BCDA7C20E0A073BEE2EFAC34D2EF1D03BABD5147659E50B557045B2EB89DB303749B04D3 +F54B43FED612FCC68206E001A7AFE90230D9C12F74A32C7EDB5D0241DC3A5D51481FD7C8FAE08FEE +263FBCED7C7D911B3A303C835AF5FADFD218F61A9D6DE80485ABCA88200047B094441F7767B97A24 +E8C612590FA2407BAB1E8B56C71914EEF2355DD97CFAFCC192BC06FCE063D3D9D1A629AADC75E3BF +207234C208E7E30663EDD691043065C9CBC473D97C6D4DD3DFF59D6A9ABCDD4412C3128F603160AA +D8F81C6E7A4DCAF35F3A99B4EA10A34375B477C2BF846521A7EABD4D28078E9340452A198F3F5ACC +3DB7E3908939FF6E3709C6A3FD9889439A4AE3E10B618CC92E14B68429A3AD2C80940A1079452EC2 +66F254657BE7D79A2A24084AF73F6DF71FBCD32BF6913A3FAB25F977787F7BB0C3A3E8BAB38D7A2D +B0B4826950643DD1E03BD7DD1FB149A33862A89226B7CB454DAF613128C2075470E42E70A9444A8E +6ECA526345AB48E6F5160BA23B5BDDFDA6049EC44ED1461C7E0DD514B16E2FB285F72039DE3C7982 +EFD40D7F6C8E8F4CF35AC71B467BFC578002E8D2239A2FD2C4BCCDD8AF3D7DB1F4AE7F2D2E0811DF +9D0155BA6EDE50B5F052F14F6AB884FFF244D8806C07EBCB49ED22D85DF696995991A954AA97A1EC +D86ACD76E061B7541E87997FEF0657A826BD88EF3A4A5920462C6595E7A156F453291CA044CED810 +860C3B0149BCE73BECA713040664AD0591304106129600AF71317B0D2907839CEAC99515D357E980 +B1937B6E1200AACADA205421001F1B2F91753E80D2263C56AA164A74701A8D5FD28E46480B0DD963 +A683A1F355D7FB4463C7347C94EA5E2CA40B60B56297CB22D972C5BB10E56715A955605256C1541D +9F3BC5768A6F355CD3B863F0FA1A781EDB49368F51B29481CBB41D4AEB07AF9DBE8F52C5D0FF75F7 +FB6431D37D6AED84D78C778871CB0F715B4F07580F23B586C969C81B471FF6A6C7276F7E141E02A8 +584D4B9AB00E7BD643D2C3FAAA299B1F1E25048461952EA42D4882768A70DE46B213A287F8D31AC4 +6D5436F22A796C05D1FE50A9BC2A928066627A0D87DD57A3AD91DB446404B41557D1457873482005 +EA20916BBE46C613F456C849D46BA79D20627B446B2F49E3FA309AE14F8C420CFD94922CBC0FB9D3 +5A0F7DBEF577F1849A1A80E0011DA8AC082A8C6F61658E65AD177ABDF23EE17C8CF0D26B9FA3A6E9 +4837EB9E930336889767A8D7EA3CE980A8EA95528B004957BE6067CD9BD8E02A0F23CC1762CCA656 +D33412FF45E917FD4A03EB6E8C1F43FDB0A8965A33B4FD26BC24A20B304CA817E88495BA9B361A3E +933717FFB0271F7F70C5D3CBA1E86D0F51BF3ABA194DAF32C35C796627D00C7B2271ACE2463E37E9 +7B3C826CF3DB60028F240F9452CBE08F7EBCC5FDB1BCBB3C327A9F450B9E5671916101D6E3E5E458 +CA31F04D12F592F83BADA2C3683D3886AA3B403963AB5DBE220FEC00037A745839F67A3635DFD3BF +F08F367482962DED88ECF6322852D643A54D5D303EB04BFDDEE9BBA1EBCCBA7C653B3A613A8E719A +DEBE3CE1BD7E754E5F4977E863E3C2D388A65227B451D4F3A4F94E06513CBA4AC1F2F511613FF035 +611684CCC461599000E546E4D972CA6960E095A526E4735A23421A4C9B597ECE08AFA2753592BD16 +DED93255A1E33DEECE3C5EB77B94670E8137F2A4A4B98AC193258E7DEA5DB8408A806188F2D1DDC4 +40CCF0E9A6E2F0C78FDBD7B68DD4939D2458C1965BF8BED4564B32462FFF3EC892C03B11D3EA813F +AB4CFBE8D3016329C5B7E3DFED0F08284D44AA0B7A2F6BC96EA4503E8EF52A64C22BED6B452581AE +8FF8917D53976471941A9116A2D878FB2541B561767ABD4E31CCD8A590CA03494C62AFFD64EA0A1B +C779173DAD84999C7A8D844EB1259DE7BB5B25CD023537A474A524EBE4660B22568949E624D8FEA0 +AD37F4CE1EC75955EEFA49C6BF1803BE87E9C9865FF3F6B8525B8C15FE8835CA153D27E6C0FF0CA5 +1029A7A9185D25F0F14D86FC797DCC1F99EE97E2054B9C2A2E06FDBEB8DEF6CDD368BF23A858D9F8 +C1DEFDCEAF1B4A8DE5EAFC604CECCF0D285BE00AA912EAB66EFF4D37AD2EFE34853BBFD87CE09B18 +749B489943EECAE7887B006FB827D10191DAD18466CD1F86505879310A8B171F902EA0C26A388E13 +B53C700272CEE2BFB47ACB58247C13449C6BB9D01232C32517358F1A3DE064D43C18F8827D53789C +CF3CE2EBE78949A6ABFA1A6B8414CE360A5E22AFB7D1DCE6F5A06182C3B984B4F9BB1A905A9D5A14 +83750A1DE0A857CD5C06945EB7D4A2A6BF1237F32A154FDC06D51A703D44FE052FD3C53E9E8F417B +35D1C851F9203A8997521529F21AD8498F96930AA77EBAF82EE02A57BC77C792D9F220294B45F48E +A8FD94E01CD25645D36D168923562F3FDC93CB79DD4760DA0C103C2675722D7A1B79FCB4245ED12F +A0DB52492C9CCE58B333CFEE822812F7DCA68E802C451B5CFAEBAC608B950386B6C58239D1C62D62 +4DD5D15782FC552222CCA06DDF387B373E32C3C2864C63C768350C37283760F3515A5B0AFD66C48A +B522EB3E808C061F5CD6BD96CD18C9839D30508E7D4EDB88E8F11E31E10919B16B7971F06D7877A0 +58D8A4944C84FC6CAEDF3341B48B6E0D3C7B85D710E0C35F5B5053CF4B4798B3778CC28B2DC7AE0D +F3A49F9F3BCD8E95D746C35C3F47D68B8AA35D97AA08E711B5FBE70D1A623C82541EBDC51A827D0A +69E6C049087AD26F256EB7577F58CCFFBCCBA5A95D093DC29464C9A38DE95BC6B1853963B2DEB0B5 +7AD1248D6F1625E115EEB9510B5772AAE4E3C866657DB0B3BF0E0AC345E116F8D4976B770876FFE3 +748C36165522991F46A36F193DD1A1C94713673C7E4C81582391B636C72DE94CE6254374F99B623E +5686C13D8A8322E83E11BB0B0A896C6A8C2C4F756C5385CD7017F26D23F7C3EE97372C868C8C9155 +81723BB6B76B4C3CE8998E4FA6CA40B633DFDAA59BA902A4952DA90EC4FC3CF0F2676ACFA7F76F78 +236FA2DE10FD3545357215246BB7E527F277C28B353CC6D79DCEF21BCC8F77603CDD58A2CCDDBE3A +9802F941CED8E035313875319548C41992A2BE939A17CC109426E33825AE59BCD17CB19F50D972FF +CBE7D9B4B0BB095303D9DC9D406696C2508D6CE99E11CF00F6461147E97449ED5F486D480A86D3A7 +ACECB7E9A945984724EFC21C5079B1FD03ED803C2DEAFCE3327D2D7827715FD65D9506216C88B0FA +26935E95C64114A51919D419038B1A7E9C1E829FBFB53275093752DF19891A97F3CBF7719C1FD6CB +17019A6D2D25360ECA804C4B35172662CC4769D2B785C6C87E5A4ECCE31704E59F71263B7C3CAEC8 +ACB4C7426EC25F11A0042323EE6C3EEB04284DBAE2C770BC419DCE79BD4560AEA41571C3B595F525 +60191DC7A8FBF63D413A77A0905E517441B16C2B501EA2F9E99CC38D052679F288FDF1894542E3A6 +6989A0090185EB2E75134BFA3D9147C3DB8A621D9D35E37786853779E157B47F71626D6B3E633005 +9159C17596C1B87FE2B4FF47ED9D78FA4C2160077276C8B58CEF5DC030B4A5D83CF257096C047FE6 +4DE307C598B815058E72D5F57DF5C369E664E137DE29349E2F9DCD8C9F4EBA6E765B6327D7A20DFC +B20711273FD8091CBA605C4C494248076F7E03DF65A6A50164980BBBB708741E5BF6056E6F996DC0 +7FFF408C5B8EAB8DCEC315E92873228C805D4440A6470E3EE3983758DD211C9CECDBFAA4C9300CBA +00608A4B2404A3C7AF017A3B7E67F39F0B51ACF950D3E75CC7BC2B8D3480202FA958E8EE0B240501 +5232EE0D264C7CA02C18CA45CB3C2DE322D3EB7F00F9455DB6C5B1F4E59C3E95520EC36D7D903CBB +625D70B54BF6F8255E412604BBB29FEE026CC660577F91DB1DB4A613EEEFB20CF7AE3CD89D565AC8 +38416B01B5DE4FFA5550D17FB51FBBEBE21CF1D56038863EE931B90DEC2E211ED42BA92EC244D4CE +2C4EC5CA87A026992772DC2AF754FC982B94F36EA7B7BF75E0ECE90CBB2A6AA1A012E8898BD679C2 +3CB3827C35D5D02F0569C7AA82615D4AA67518ECF668D3B57D6EF1A8013424AC2268BA0D9A74D588 +79EDCF6382A89D397864940303EAEC45A38304BA8B1CB198967AE23EB81054BE74B16909A405E8A7 +799CEE3C270FE2A6DC50BD7370B6B2C8FDB9A87D88D5D40348D3984E39C693B6F4486D994778607A +80A3122872DD65E40492107C71C3CF708A9717E9EEFAFBDDC239C53AA9645B711038E59C8B861B37 +411AB2039BEDF9CFD00F08D9C5D76154427FF5DD39878CECC5D7BFB3F1F035087185C0981F3C2139 +BE84872FFAD3408531C4EA9387B89F5E3EC779E8850D50992DFDCF9132BC551E985943B07618AC10 +D1150451F0844C0DC41D6E17EB508DC8689EC726400D5A7F6FEB3CC7BCE05F09228B7CB2C5393664 +D8DD9A4B96B1020EF25D70AA2D91CAE93AFB5F2BF0AA18CA5C599FA1A708EF35BF8F7FFEC9AFC1F2 +42870D028B2B1459063B493943EF1283829783E1010242E5CF4DA39D93D506F3892936E7D6CF1124 +70A521D397438733D053944CFF12D6FFAE8246F20618684F263715AA98E15D72A526383E05C23214 +B78338E5B476F0981D90056E6E5D0DB66B1DF2298E597B2ABE1D817E18BEB056E65EDB4234342D96 +00470B1420C9210419D834E431B82F58608C87AC361A02D0F1FE4B470A3D71E0D21BB87E1023D428 +E23D596CB9E1A2184403A16E36E644BCCF9BBDE27290485057E62827283E7380AF786BF395B3961B +A5EA469C315763FA59E0F176EF81985F38B882DE56A74D128E256D1B89939728E55A92ABA21A6B78 +44FAC1BA7BBDD8B34A18194A2984B000380FE9F672E83EFDBF276FE797A325815B0F25CC95C97A9D +ACF56D583486305D7C9E51A7E337D14E3B900333EB38FD93A99587DA2341B10C059C71CE080FE753 +3C0F059FA40E560AF9C4A41A4BE6FB45846FF8F78165E10B4AD40F264BCF5596A1E8EF8CB6EA4B1A +3A5C69059AB1563843679ECB2511A90E8898F54295649CB73D277760D8D04ABACC7BCC6E777A0530 +E2067CCBC08673F9C8C178F9D672AC8A15E5367F0C5651B53E75E0CFA57C931746AE1A679C246D7C +9417F1CD89DDDBD1173C2F880B7B3847CBCCEBF99F7122E832D7C9BAFE2B54CBAA1ED48158DE3F36 +238B76B0E67644A28AEA996DDC006F6AC0242E4B667639E7523CBC90A0561193C1AF34481C2EF402 +EE43A82E1EBF4E3D601BB36B2D95CD93550D61CEE7A94E72F6D30C32C8F91A61E964B1F66ACFC398 +7F95D4028F116E9A9A8474AA29C1C1A984BE0E393BDC41DCEF6A6F1018DB60D52024899D8EB5D55D +324D73F39BFA47377B9E15B3B06A7585589FCF52A54684173E5183367E7B0952DC4BC2767C4C6247 +B1D6103E52BC7B7EA6298F454C5D97AC575F19C10ACDFF4E10C7D3755CFAB4200CAC545269FF1D8D +B0D607C7AD47F40DDF257AB4E7D0750577003C13E4941960C3DD7B0774DDAC18E8ABAF8F53E03CBE +F6D57B44F24CF821014C064278FD51B3427593D17694B4ABCE81F49CBB984C5878CDF0C38D1ED7FD +99B0B9A3BD8D8FF6219588B3B8FA59D0CDD1D9B2F65122AB45E48F1757467B9204926140E3C350C5 +A927A2E700173053EC35D3F1DA2D7258714C97FAA857F0898917BD94625C6D1E2D77138EFCAAAF51 +7B17FE187A2212C24A881A2C6A647DEF6376ED80AE4175C5EE80921F001995B44E49F0D33DD9075A +CF33BB03671C0BCC34AD5784AD1CDFED3A6D9BA103B3DDC1CC2DE74DBB576A0277715275218CD19C +A8899209125266D8BF1286F881DCC2C383749D1E768D670F4099F7DE959EDFE852583183C9111601 +2881A56A24AAF020EA45CD5F39660DEBCE30AC1C7B8CFC60387B1B0C3E361BE612FDFA9F01B7E4B4 +A18839A2C7E0E393EBC5AD9A8A4EBC316A740C1C295D9EF5F4DFFA0667F9582C0BB837B142C4CFC6 +B1798E9476D0631111033B8BA75A10FDC800E2AB1E0E829632F869CFE4737BE9E2800759EE0831DC +7D1195EAF80555771981DD6DC6606812D92CB8EF86447F5F6C6F626D0E265C67E52A6319189EE349 +D48E49DFE6A9E98F76C414A1E3217AE0A215A17E54AA498F4ECDC50242ACC7E2322F63BB2FF2189D +057E7354E32A3ED1803116176B9B9D0129930F919E2FEC280B2C8924E49E7BB75768A2EE1DA8ADBE +D4E3589906DF1B923AEF84C1BD327438B731012E69BB0D43A1842CB88BB54EA4516477F704CFEB28 +6E3EA483445AD4D74586FCF32E96D366901084365F693A53C5FB532FBFE7BC0CADC404C4985042D6 +8DBB90A6DCDA3531EE324D558A214F935CD9FCC9A0CEBE9B5FB0323F4B3820529599EF48EE068B5A +CE85004FEA2984F0A86F5AC9D56163BBFE1142B774148F1EB0A4DC89C3349052533A7DE66729DB24 +41B82F8F7360111DACF69293C9B281A0534F3E9E9224A75C49A832F28B2E497262475507B6DDFA9F +01CA0A6696E3F5AC7EA68595EBA0C2EB8A47813FF936D84AC1B23ECA7AA2862B793CCBB0DF9FDD49 +31BEF354CEC12FBF478559FEC29F81ADF4452E83963E56541D31F3691C93A50F0BBA5E9552C4F2A2 +3A6E53060729854A3DD71CC4308B91957DB19E66AAA18FA67055A950F1C2CFF78A03BC1A588CF624 +696068068719AFB1001C4581EE072113882D9052B21E355D401ED8CD24D067B99E616BDA5A0A5A93 +36FC499632B79FF2FD0DEFB096EF46B75E2D4E0F48DAEA239719FEC4D9A29818F5875FC5041A9EDB +D26CAF0ACE14CC80BA49BBA59E918EB3D8F1E541AA16026585A2F72DF7D83541816DE46981FB3EFD +0C30E458CFAD04C79421AB7C4925E23AEA07F9F018431C790002596D26BD9663B51B699DF53E4882 +CBC34EDE88EB55045B889B6062E35FD1E018BCE785157B85EC3B9CA6C85D4B16238275385B8285DB +012D8FB7C9F5B946A41D7A0FB878FF72C39683144D8A007CFF631B43748F2D5FC690300F9BC0C837 +006B92ECEBE0605E8C3A4A400E18AE8997D1B45FEE10068E247C647CF82C6DFBE5E881D511FFA687 +B7AEB78546BFD07D5F7EC242DCEF4930D8AAAD8C6152B6642AAC325963FD147F236BB850A9966573 +9D06CDBD7CA79A527DCF461E33F22BC9C5DB00DA2BD3DDDD8C99D99793BC98282AA8872FF96C3942 +85D82D9419EB78B6AE37A5F519397700F75D624A09BD255B576E955A323E784E8FC31131F003B0E3 +024A4F58FEF2A6C043796201FC425482E1155E229D1B2D43EF7B0D22322B22EF5C9A1BE026A1C3D3 +75EDAFF99597E1E5477952A4E8D2ACF5D014BC00DC2A272FA62B6983E27D228881E2EF2B8B95A681 +CBE90C5FDE16331C85222FE2A16F0A3C3000A63E2E21666C0C119F8AF89A543D37977069A5ACF155 +6324F05204CE8CAD50FF4FB630D9CBBFC324DEDA584AA56A99D3A76FF55BDC2C2EA3A021361CCD4A +83C7A5E2768D210FA6DE889FD48A39D679C94EC3C99A8D33FF11377DA7F6F1B71A2A05B302ECDE95 +4F26773F39AC881542F0D0969C3995C3519A8EF70B4220D86BF01BEECC6462855E7B686E1AFF1CA9 +1FB8FD8B4A69E10EE0C2AD94ADD44449506F9B6EF43641F2026EFF6E605C670560C2B74706FB949A +A7E8CC6A2D0D6207E457E7FD87EC1B9092DC68B9143947CC8ED14AFDDCBF8FDDA228A76847F96802 +E561F67CEEFDE45AE587673983FC04C96744DBAA83F2DC838D633943C75DCB9E6410474EB27B348F +26E505F0AB90878940E846C5E9F3C5FE8C3558C3236B1B88C405716949B8506841CABE1717474BB7 +C30DB91CDEE33B0F844811762FAEC535BDCF84C1C747CEF9B1FA61D2AFB5A81335BC42C06A94D7D5 +9B7EDE55BCF6F9867AEE107555CDD084B7684C2C87087475A39A9DA6347BE281CE5635A4D07865BA +98CE26C1465B1AB0343F49FF37B4D0CA9F3BB693D78DC3B21925CB996A038DCC172527FE57C07460 +EF39C07D4396E7FA970D9F22ABD21A9C794B64AD96762C7428F59A8757C36D6C4FFB23216195A04C +2A2C2E7B10EF7193931544D782FEE4B91E01119C5553BBC6252270A8D8C56DD62D448F5AD8DC69CC +B45E1F17F0AA1E445129DD00F000005B23D38DE93A3BE55A4C041947F36B4E4536E307D0180553F9 +2E46B743881CB5D5386C48C7D5F84C2BCD06B9C501F78C7EE61FA23516791FCF4DB278AF688A2E60 +10A56692AD92008497487EDFE4BD5FA083FA544138B20D6940020887E35D46E093B71F7A04A67460 +DC8116B4D4839625D7CA6959D6831CD93F81AC4EA2709036DD738364FDE71113BF22EBF13DFE1642 +E564701E6F0FFE7511EDF03FE448C2B28C64FB7D54B94CA576E481FA56B2B18AF10C71F699B6BFD4 +7459CDE1869D0FD306BF489A6F42E5B2F05CCF55BB6B9526973D19CB134CA7F13F1DB3716F8CC217 +73A832568C16250B5CDB16DF24BF81D49F5B37018BD310262EA7078107868AB0216CEC83CEFCAB1E +9F2C665A31585CA04DC01879CAA79AAA5AB201B516F7052B01B16BEE5606098393B0E5D9F9E5E3F4 +EB20F63C958E796DF41CF28839F5C62A0431648745D7837B519F3AA36BC6C08EF040CCF53D9B6D8C +0C7D1A84D707EC57A3C6AC9A62AB37251A01A5ED40FDEC6F5BE6E34C6A91D058319439778A2EE5D0 +363E2E1F33463C33327D05FFC0CBF08D5BC457C7230448972FB9B4D0D782BA7DBF10D3FFEF8BF523 +6EC16D4DD6D0D870D9D5EB5C64C9A46A4F583D4F831FEE74B0E5B33A09ABFD4444929BD8F638CD72 +EAB99CF2E9551DF427683964A592E49D186F285258C5D5F62196A98532421D73E3495F82695FEEC6 +E1952C562D546B28618FFAEEBEFF03A57F4D855021F85B0C7BC37FCC6DA9AECA099B646B99D41896 +09D3FF2D56422F8C37E97640293EC7C90E3380887836F4938FBF495CAC14FBA5648D89282D8D49D9 +1AF73ED36581139D8BD42551E263E830EA3C6EB381D85C42D74C50DB0CCAEC03F535ADE92128A016 +0E811C34748309AF7604919B66CD43EB5CA975302DCB6076FEB6BDD6FF55976FE990FB0CE9ABB11B +195403FB26E3D6C6A0DE1C5BE79E171A61E21F79EE8DBE7A832519813EF6B33EA098C2C32ADEA219 +AB2AAC8B093F40000995539D1276D5F2EF84CCD099B71FE4269BDBDB6A8D59C86F7D2E3FBCCF8773 +D0FAE97640BC1AD43CB4B992BFADFB09DBD0CAAEB8CD9DA264187C4F97300E9A6C9DEED5525479E6 +05C65AE336CBBDF4E5D7F79AD098F977285E065579B748FEAA97F2A753E1F962FCAB68D72BAA8EE4 +FF6691C23E31BC0F3E981A96FB440404856AE1AB32A7205B17D411D8F21C8C93B704D07EC594422A +BC368CDA2B1610CE6A973F4474E12B78B532666797F5755D269772C9F5400B3BFC6C58395D38527E +2CCCF29B56123F7DCEF3BDE5DC1DFC5B0293BB125085B1D2D929BC3EE84F4FAD571A4991C3DEE03F +2DB3A3097E52B1A7D5C73CCB6148EAC62E8E36DE9A71C57638C6E4D5D9DED18174E8C390E50B4A5B +913C074EEAEBE390B214B3A68F02862B9A296DB4B409769649E51D738CBBDFB7702E15C73C2AFC6B +C37CE15171F4E822CF20EFE55D9F061AA43E648989628FF79E65932390CBB15D8E621333B18B11C3 +BDF96F841D7434E01AD501FEA964A75B248A35CD9DF9A37E48A1E5A09C624B93CE44F0042FA00D7F +9EE89B9F7AB785E9C718CF6E7228F743271C2C9BBA17E5208B920E44E765D99D86650EB454B0FAAA +112753AA1BD3A24239E9C5FC47EEB1547AC9D23731B8DC48B9707830DAEC60C8D3790BBA1120F776 +4EFAC542CFFBCD5C05F9510B27B2534B704ECD36C8B041FD49A96881302FFF5B0163A2DD09C751D6 +D6AFEA9170A4F4C4AB8D46E62F763FE1BDA51DD1CE4A27E772F3A2869155F762FF26B7AA6FCFA4F1 +292E56F03AAB6322BF867E7710C34D43B5D85B45AA68014AD7879EED051B1933E491496E3E26D9AA +8B80A07BF2B94F1077E84A9726F08199887D66DE7A307BF33C30DD9CF3DA188088C03B2BAD09A217 +6B110DB2C868B53DA9A66C85737BA66C93C58A259860E294AD0191E3A72C73F40B0BD98699AA08DA +F03587B78F391F3A4313C58D9F29B53C70785637BD0C58310109C54091AB0A34CBB0C478613A7AC0 +FB8F0A8B4645AC966395D8BA775262CD291136AFFDDF01C1D83DD4EB3B59CCAD18057FE7D92A8CD4 +A58F22508D9FD7CF356571F701BBB23E749BDDCBF8A317FDA0AEFD952BB18545610FFAD3AC143D35 +1B8DB3F66293375E0E50235F0D0466932181D377EDD32A5F0FFA4E22B5A0CB4F343D9A7E4A342E9D +09DFF6C697630CD3971802C277A5590B8CA94BDE6B38446C794D072BBCCB724D5BC208EEF1B018D7 +39373BB910D668882CAA779C2D686081DE6A2606417B54D7C20E0E7F722648D893E4EDBAE8F00D6A +6DA3712F91AE860C756D1127D133AB828E9D80023B50B162C5A1C5CDF70CCB3FDD7EA060ED20838B +E1E50C4094C9E79E1A0187CDF780CAF45A725964F004253E034C5BE46BBF89D94631F1A33BAA35B8 +4FA2A9D08481C6674126CD96ED05DCE48BDA069D902D6836D5DFBA701DC0F98A863E64F0E312145D +8DC0B77F25B43AEC729A1243B45B08CA228DD6101CAA2AC5ADCC8EFF84A4CA3F254176C2CC711EE6 +C273835D0FD3528ECA2A976B88E51FE347FDB60F32370B66D338931D6581630ED586F349C638960C +31AE4204E89521A96E1219E696B913DEB2AAB7A3B022D06F34FDFCB810A04E60A4FEBE284C2F063E +0AE9EDF87704921CCFA193BDC912B747E13570066223A49F1F6E2AF0D4D65DA04CA876FF7A462FFC +9C0BA2CC545C3BD36DBE762F32B2D6BE5867C59F479195C92440DC165098B74EA5C3AD93CDF2D410 +B04C16BC7801E7956F4E5107450787AA592493171C3628E6B8F49D4F8429EB98DC52EF025F001387 +BC1A7093F7A99F10B5D2D7DD8BBB393BF6E56F08F4F7FA1A343F220D5A1EAE7168C74D41BE1DC1A8 +3BD65B72B982F4F7B34F24F97F9EC9A91011064031FACFF2A14921A32024385F4E061CD07D152E74 +1BF97156D951A342488FA7F5EF934CCAD13E2753A0AB7A1F565C2F7F6B349DF03BBC25BBD972A9AD +F809BB5C5048A8CCEF9297B2ED3324D18867F293CC66E88B3A39D107B610DFE79A3B4E83A96D3D52 +A17FE8A62C9FDD271130148366942C9CE57558D023DA5F7501319EBFA33DE9E6D1E76D7C20DB8A09 +B657839DA99F3D8143F1EE6253A3295C9651FA4366547893C2DC7ABCBF4BB7609DE5D001E0A36D9F +FBE01F7D0903B3208AE8547E2E5F14EC1AF4C2535CA8F4EA37E3F3CE172C7A1E8308995B1CC23E6E +81190246BCAB6E755BF868D449BB02A2AA87C44C9CC0F571ADC72547CEECBE104BB274B8AC16DCB7 +5D5F458D356466B921ACDEEAE384E2EB1DF6EF393B41B9747F0A4FAEB4AF1928D9AD6FB7E06FDC62 +1E4C6FC98CFB43F88584BD55D9B97CC9549093EDE586912161931162B1B1D52D0443260DABA02AF2 +B4432100D5506546013DA703573FA8013685CC798CE501960093DED713FFCCF89CA2B9106390198C +29A00864108CDCC1984A8BAB53919028C01B26ECC7925E38CBE6CCA8978EE21C2B06E7B3E48FBA97 +8E2A7D186E563C088F84AA23178B60E4729EE87D67B1091F3B6973676C1CBFE6530EB773C62E2C24 +97014AB0E8B71A1F4E86A378AA26591511BEE3CF3D64C94848582E1354E1605B6457823F2C5E640A +D3802946BB2E7E8E594E8C04B430C2385DD40746CE8534F50842E74D7115F3DB0C72D1C9C607C657 +3B094AEB73B7A79876CFFC3E2F8C9FEAAA07D3BFCE05B61F7749A8793BE90CCCECA2D7077F25E899 +D3331FE161A7E86C842495D584C6E4A0880B2951D8A13B88C4672080A0B1BE36BF47C3ACE7288CFE +41A8C1BAA6F0814A947FBD6B3AA72B6C73A8C578CA51CCC96F2352316C467BB960E981F2B6485BFB +44B577E71EFDA16E7405954BC7C9F0759F5A9F1EBCD2FA9CC9648D5831A68887F41B15081A204C24 +B4B992A231DEF9E698D4C3A25B6F5474F5BE6A601F2D337A58A0D21FF37FD91EB86D1D738893A03A +69F0CD743F611CDFFE69DB2C6ED0E4611D56F803BB0DC06E7FE85A303839612707647B1BE9FAF8D6 +84122CA9E5CB8BDE2936D3F4FF254D31529D7538BBD4D35539489F9E7316F24214B996BCDCF1818E +749A71CF0E8845AA1E2A58AA62A48E02BA4564625D20AA220EE719608521D7D7A7FCA0BD8904A401 +9819D371F3F59D46C1354E5FC1A6E5F79B20CF4ACA2BF0F2DE73DA193A6F9ACBFE0B4731C4BCEBE6 +D96FE822965DE965232282A3A130361F188B3AABDA95A8A2790D9240BE008B6A6DE4BBFCADA05B67 +86B9BB8E0DFA0C30043A3B07ED46277E07B9808422C8ED16758B9C396F4EA929D769785B2C9568E5 +70A83B989B25CE200F1727D41E2B702E7F88F1784F4C83FA60A74EB26B2DA95126E508ED519A61CC +151DB6804F61826C5F86D8FA89D06E526FED97A0DB88EDB432FF32C1ACC9B622EEDF601081AF7B96 +3C9CFC1D13E4A9C74FEA0A1C8E3D8653CD92A944D4CA6B0D306619AFD503506D77732D6514F604BE +4610C2560931BDE0B40939BC1D126B0E97F72AE1B4A9252123B54F7A27E0CFA4425B4546526FD741 +CA77952B10D13E0AC2E32006A903808FF0CD013F936238C74CC75FD915244C56A8412F37F0134840 +347699508D6F3D7F3203A25B7C70100719582CD588590EE34B3AB13E255B613A6D00386A0104CC5E +D2C646F09A88888D3751651D5646C5227A3C80E8DA1B0A331121DD2429F1F4775D30564DFF47D01B +BE2C6C72CE4D1FD9A2077C04D2B0274B8916F6A9D1A4A6964A534F47CF241D5A8E34B23F85BE9ACF +FC2FEA961F277539F215F8728D6788F67BEAF45502839BCF23D8763C3949352F00C579A9A4FC408E +C625E310DAE61512DFE6844E82D36A2F81709E1F05B38AE9C222ED62C961EE63593CED7AAF73CE2E +D3667740C77B309B93EEFE1B4BA65D48575A66BE86743DC9E5D3C2FF418D11F7F211B86E827EE1DF +C3613E7498030F07050524536D1F8A94DDB6698BE7B963C55CB3F74B676CD815A7B3DF4B1A0EA2BE +1B0B9A11FFBFD5B1FA49668AEE14629316AF436A0821C20BEEF7B3480847934A99F6D85B68F4DDF8 +859A754E009428AF89A90D1852C220A607FF0806E8080726EDC94D691D214B4521C147C4273AEBDD +BB4A697EF16448CD9B2FC95293305858DECFD406B89B9F3FDAE2AC579E80CF321EBAE5701FB2F7CA +D8ED04B4A63115886D45D6120F69AEF1A21D80AD3C2D35D2899F1902242B96CD349E0AAADA40F7A1 +1282B6B52BDD97708E58DC5E2D22D1153E5FA3F3B300BCDFAF98DEC2F4E3C82A1C85F985735F3987 +4F557579F422664E07CBE19DA680EFB0FC82C323EC5C4644C51709AC8D674608A8043C91E6C7988D +430F10BA6CE1FC7FC0604FCD8F723895250AEC36CC35B3FA14FE2A0D24095DCC30B2093F2298F5F0 +A97676A0BE66C3DC9ADACFE2FC0F721A20E945AFC1096A619075D5E9A264C796EC6C90EF1AEEA8DC +089B44FFC13D27CB2370070A52D4416C53F364393E46EDD7EDE00799960CE6E0D57E4909E88ADD64 +BDD2B0EBE2D73FA6ACF8B40280DAA0637E705C65AABD523B8815F22F23E9FF81E7829C7E4BC980C9 +143AEBE1A04DC0D253396BBB7268BD5AEEA356B610D5DCEE03135E00AE34388251F31714A1C40E18 +2652C48CDA2211A22CB6F02490E69A44CECB169754C53B16028D352E0119F5D5FAE0BD7EA1CDA647 +12A6147374B64244E21E9EC9F0D1381AD22D5B6212B26C3F9AA5F6045F25DD9F5EB4489EA39B1945 +331AC70510C5752557DE21D0A6CFC1EB10A98FA867B76DA6E4249469F591FD154D39E89364A43DB0 +07AA0D7A911CFAE6CE2B557997FBC44F55A27F622BD7B8B10EC9F5D10F2649A646FD964AE1B111B3 +5B46A252C4DEE44E7426EB5739F24E8A390694597DB3A1FE7800C97E59558322F0E49A0CCE2AD94B +1E2D1026AFA771723E3F523916F55ED866C9FB4A2F759651C613A2CFF362028CDF9D38F05D4C7C60 +24C533E930B64B099FB1AF04B01F5FB9CA6867E6EFF55A772C5391831059987E10CBF987E3F378E0 +1329F73D54DC0484177D3C3C06F67397955FF1CA4EF8AD1606B70455255D631A7D6EB92BFDBA14A0 +FF28B2ACE7E81AD666EA9B3A0F5A6BA3B5DFE35044FA4B3D8ED956009C60E98CC132F2E84967F4A9 +8A67B336D5EE7CAF7DD1F74D1FA08619941361FA7312CF225D89CEF97E864C8369EAFAB94D97F056 +5505D825972B754F6729596EEA91210B75DD8F645382ACE36DE60819A02B3B48DD00F5485F9264F9 +FA926D732E2C267B0BE8CA98526F124F97EFDB86132C5EF16B103908172FC51F286FFE45FF253512 +E0033F037FF182BA536A9EB2DF2D1DB257D9C86C46E1B002FB32AC70CA9462E6EB48994752CEBCE3 +9F08ABD4F4B0889283E55500702185A841E328 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%%EndResource +/NimbusMonL-Regu-iso1252 /NimbusMonL-Regu ISO1252Encoding psp_definefont +/Times-Roman-iso1252 /Times-Roman ISO1252Encoding psp_definefont +294 310 moveto +0 0 0 setrgbcolor +/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont +<4558504F52545F505953435249505453202B3D20534D4553485F6669786174696F6E5F68657861 +2E70792C20534D4553485F666C696768745F736B696E2E7079> +show +294 398 moveto +<69666571202840574954484E455447454E402C79657329> +show +294 442 moveto +<20204558504F52545F505953435249505453202B3D20534D4553485F626F785F74657472612E70 +792C20534D4553485F626F78325F74657472612E70792C205C202020> +show +294 486 moveto +<20202020202020202020202020202020202020202020534D4553485F626F78335F74657472612E +70792C20534D4553485F6669786174696F6E5F74657472612E70792C205C> +show +294 530 moveto +<20202020202020202020202020202020202020202020534D4553485F506172746974696F6E315F +74657472612E7079> +show +294 574 moveto +<656E646966> +show +295 691 moveto +/Symbol findfont 50 -50 matrix scale makefont setfont + +show +370 691 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<46696E616C656D656E74> +show +595 691 moveto +<20> +show +607 691 moveto +<3A> +show +294 797 moveto +/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont +<2E2F6275696C645F636F6E666967757265> +show +294 841 moveto +<636420534D4553485F4255494C44> +show +294 885 moveto +<726D20636F6E6669672E2A> +show +294 929 moveto +<53414C4F4D45325F524F4F542F534D4553485F5352432F636F6E6669677572652096776974682D +6E657467656E3D6E657467656E5F696E7374616C6C6174696F6E5F70617468205C> +show +294 973 moveto +<967072656669783D736D6573685F696E7374616C6C5F70617468> +show +294 1016 moveto +<6D616B65> +show +220 1128 moveto +/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont +<6FF920736D6573685F696E7374616C6C5F7061746820657374206C61206469726563746F727920 +6427696E7374616C6C6174696F6E206475206D6F64756C6520534D4553482E> +show +280 277 1 308 rectfill +2125 277 1 308 rectfill +280 277 1846 1 rectfill +280 584 1846 1 rectfill +280 763 1 264 rectfill +2125 763 1 264 rectfill +280 763 1846 1 rectfill +280 1026 1846 1 rectfill +showpage +grestore grestore +%%PageTrailer + +%%Trailer +%%Pages: 7 +%%EOF diff --git a/doc/salome/AddNetgenInSalome2.sxw b/doc/salome/AddNetgenInSalome2.sxw new file mode 100644 index 0000000000000000000000000000000000000000..15381905dbdc2d5bd91fb9f039013a733fea0b1e GIT binary patch literal 13363 zcma)j1yo!=(>GGII23m;?(XicWs5BfEbi{^?(SBg6p9omE`{P0cc-`%EB0;s*XKF! z`<^d*a?d35n`CBgPIi);s42p}z=8Ue@KhpM(Ld9}NkZsf83mGUOg!yfU6_F;KuZub zr0gIHd8i>lLA~Jki*WmksQrsLhY(t*P*8}B5RvESKLsox1-0LuAwnVk?hFF^JH3QZ zKzlnEkev&Qhpo-=TY2X#zO;_<_gxj{0!K=U95nAULGJvvpfc}m8YU1(TT7ds94je7 zK9PyVu(g=-0B;1u!il+p>1w0emt)RCGFg5tS}AFC&pHAtrjQ~xyiTdFVnI5^11$te zKK9Uves@cUg>fvA$7<8_jIUF#uqeZkmW&Y@6?bx9$mc>P?M+M$G0`ZP`2`3Cw@^@?!kAvSzWH;8HDAyKIvc>G4*+>%e4k?rV42#W6RF!@bFOk+zNttovJZwhPJl08T&V*2iDW1o0zO~ z0^B0BvwNlD+Py?>k;2*7N1I5W_|hNwHYEbmsnTYkn=HP@&*3YU)UHq^w&H4qb)#Xy zw`d9nN<6K}J2Q!R^Ck1WVx$GRutvN*#H*}gx>vGlO$jHIUhkW>xK#RlnZ&6CNa+ME z5YsR{H``?Ho8rvE=VqxIxw-C3H3N066YSu5trfLq`zZkFwmZ}&r9DtZl!uyFGaa*w1gfhst*by4`4d2Lb5Hc?r|9$T;d4>v^Iqrk zW4wRTx{T6<@Cb1i;QM~AcsCY?%ap<4E7O0_K`+cRPNFPPh{Wto<5`>6$!v(LLH^%r!H&@SdcZVyYKl^w z8)>|hd6ekQ=m10yZJS`vvVeOU)Wu%3R!3GI#VRygLEQCuW~(7 z=c{aA6=F5^Xh}F^wcgOZ!#Y%aiQRaG(2q3xs5uk$a|%ZKQ9Q8d$wk`~2zE5x5;rm3 z`d-zyI|a$XkUXs&SyKwh2#{R<4r@sflF_TMmQ;0V+|qPt+(@-(-12G_j#z3GjzlUT z`E9CN8ZURDkd2juXHO*(DDrX_Y5i+8|7L_7KHr!;hD{qRFCnPrjL`fd#e4{rWNTp^q2DnaDJ3Br7xZQz6x7|qdXw;b;;%x$x1Yw{j{p2GV~s``qq z3{!#NxK?OxvLW*VFrMAKk0cIW-4=`_%$#{(a`AA@{X6a)+s5$51uHIR}GErl}!P zV&;MpntRAQtIcC2Kj;Sfdn1lGL%waa-z|IYgI31;B^Lk1>1VSfm9#9HtdN>Z{*d^+rpnb7t32fd znS@wTG2MukBlL8>vuR05CD&XJ9;Z_~aUa+UJI#IQT&!kQloFF(@d8sx&C7M!!;(p_ zuZxG98r-G;jU_IWp7+eQCM(2PT9^8b<_@}ya6y=%2Zms4p)dN(hm&d96Bo-JZT$k- ze0!lUQe&r{G6RXngVZr_2-#%FBian4P!V+U&^nPYjZ3m*;;)4ZffFf)roA-&_tLd( z2QgElQynJ--_>UdV!JaBZb#1Y1aaHOv1jv7z*0rl@f69skl3oaP|A?h*mGOhDy<*%je{cS}*k_28cjnbmNu|bi0DM**DZ~*qXs{?yMEyeJ@W~Bb{ULxnNf8ggU z56^;;pCLy3P)MQE9W;-iuf=PE_6Z45DKtLCy_38S|H#lt<|Rp|aOIaDXq&5@On@5tJN9ruVX^CutFdJwf&CjhP6SD6_=jd-s^{qPUU`IT&4U)@ny( zk%4V(t{6XLQP?`>@g4gM;JjGLa&viA*0{Pw)V7VNhCOZoRWFOXLEF4AI=#t3gE2*j zYEY~!Saa^vn9vRP&@l~A*2xRt;D{((w}I5y4)I#9qTZ>hj8{mYvf!fwbue&~) zqP~Di9ve8|$nVw_8&P?4X9d$kMWwCxiR<-TV)Q`wqSGLB;ac>FR*41SI_7sp zmNVzG@T{BiGzUo=OtNmd_f{FGU)dHGL3s`NX;O?M1aNTh9=l)BVQp$D(bLeHpyya* z8K;h)SB<3fVjP8P54c!oGCquKszv@RK~{|6FQ8-C_`)D$Q8uj0(^M@scBET(Gv6k| zqa@k~J%%s+bRFG=N5IRP7*36DG+?{)q66pDAfl1h5502~qdlHIQ3!_yTlq1a5zAT^ zt?Vbm((VinT+t!tV!Ym`zE;`clh}SI7${l{(NRL`KFX@FHwdE*$uc$0j&8GQn5Z9N z@}VA|e%9k@uxF-WbZb=s$OLMld#ix&W~OECmA5_;LMeq3CNU{tZ~EVjznD~ctSB-x z!c(wUL;Q^Gvx1Ru$*qa1fsu__&;RL|ST(*=^0J;#v4LKs98QhAjlCp#vsFH(L(s!E zyEkl>P9;!D_VwP*r>m#i*k|jx_LG(u0ga|BIC2d<=tWmOk=Of;4o!P99%8l8CEjR$ zFz&=DoBFd0gV^p00ZRaPIUma?X7tCoVW*@LE zZD`FvtBbn%WOFSe-t%h?xEx^ewrtSdw81wlCz|txp=Rrn>P0LQNxAxo@nD|Ek#I+d z5}&+|M4`Tk%jiT9Cp9suq!0mVWg~~=D+6aZF)ys#o5{M8QR=Pi3)&p)Uk|tN<%36Z`kaGdB|7?{FsG#FEK3R zA0l)*y!@B_7;{42&)P*aWH~z4XA1J!7p&O222)Cdu3B$P3imU8F)ChY=fMYUkZrAniKMT$a;QC!CI9&G+7 zJo75>9^8v&`2D;ezfHhzNfejHN=Yrqh0+u8V}gJ~7^PPS`?o=N3>NSG=J;%aB|W}j z8B#n5)xTaM#Sv8@lzp<7MX-Htb}u)waC5pX$>lO6YhJVn+(as$ANP&Qe_uJKV*D`z zO<)+;cYSa7&?D#mXG~T;gO$?>84YcCL%bfjfDG+w~?~&Ed#=F@8#v(XfQ8;__>}#nlJt%dgq{EwEl$Hd&t*-TqLp*9a!3>%gO_vRx$;-!%@NiTM~=>FRpshBl| z&~pQRc0cPOHW7m09dy*AH1l`LBjBp<+v6kG#-YjVN?gxJ{B*T?Ro|b=eli}ZT^+}Q zT46WU%3)}xoT1*C^)%-=Vf#Pcb?RNrl${vMO~{3}e67f8QYQY&#l^4c_@S#V7ZGKt zGQdQTj?KmbK5X&l(KPH0^Z0Sj*W?Wi2U0gesi*6&FP|}?hM_IxhP4e8yW&K*E$^ql z-ie9TG*x3@IM45nwrx$al3WXfYkn93Nd-@CV5M0Soa(q0GM?{-IlCXynd#s~6AMOu z`H+mv@8(1~r~>gh>I0?Sy^@nFYOcu4#QDYoShhm%zG!lvm}@P^buk8ITW zjxXU$o*czQqx!lx55=b)1kZ8!*24GU!&h}|m&(M{O$UIcz0*2ne^LEj9eoECrgj*{ zeKsvSOz$sl`yPgfm9WW%<31E_l#J97ZS5?0SWNqEOBDW!+etOVvwiwU`T;9_ji0lv zY)^LqOKl6ip(y75RHX~gu_qlVwdm1<9L(dJ&SCTZpsM4?pO<93bB9+({!iHTO0q(C z*!PNqZ;S5z^VbiNy%cND11x!}si$R#jUGh%6QyP&2sk=X!;_%-+Hw^gok)yBv>lZ- z-78-mAiX=Npi?g%uRSLbC7+WDb=4SH9)6*^(`!y!`IJ(^VTWIrPQf^t&cN$L+^DCJ zb@SR@DL=+d9a-NXzb1j=EuhevY*wUp08G|wvN>`Eoc|DK#4r)_NK^8!icmmCifdbOt z^m%b)Ei%o)Dt9*_n+q{PhQw!3X(}qGFSiMbg@{D8kCH1-;`hj1+VebhFhoh6 ze^N%ym$;CU_e+$Jzo86Gx{*ev8H~n(LNa>6y1x>B5fC-RIwHAYLC5fFG;vwh36%$v zcIU1#rr9!!JAi+N7N70tg~3|nI!JkGK~~^6$6#I`TiF=M>Q#P20Apj za`$4H<`603*Nz#M%&DxYE=5c}5jLA13w=EX`#N>KdHO=b34q+U8Zb!`WQkr=!1K}c(U}Sn;y;`5c4>BP!pd zy&&vildpPUxE?ZQ7T03Yj}?CWHqiGAB3ZF;pVmG*T!!^Vu1a;dyTG(VYKW-nY&ijq z$!eYAL$q9*6fsHN-D8`<*2ye9=Yj5gD35C)Yep&l zd%_qivmsGj$ssXRTY_`sSdLNC)DgfUE-KK+) zemu{}>JuJ~>drSK+(*OK!GtX!oRIosLn;jWtq+FqOSZ-18Zq+YjxsN+&p+o@Z{VGQ zWufXJmq~n!E$)Qw8XjfwFdz}42w6qWmqqmKxG=nxiB>esnc5NL*L+(&qk&@IC9uZj z2QikRT`$VRZ>6gFDHk;5YWEC*P3_klCS1a@{WA8_ydMTokvP$gBAy8G3|Xew({S6& z?P=h4VnhsZgIA;2_rbF}63SrQ!9XOLKDUT0H^ql0I{)v4f=`xP%>CO7H}Ql90%u-|ZNl>+mFp z(n-l^tnke}vQ+zUoIxy?yLxZBxn~=flbL9tjp2TyKLLgPGS#-+ti8+YgWKk@d$cx@ z#@?m~J$NK0|d$kN}6~l)G0U&N~dK@~*z|YqKuTwg_&XFi1Kq7kJ!uOvaG5ha&K{ z+7DoY&PkA6j4~kO<4if6NrCo~uWRvgkAu`0i{kFMF2wWp`*hb{44s*C!DTF4+hA+L;Ir(0M*9UyO9N})?K=)MYOF{oH3LT-k^6seblWs^2X$Ga+kra1C z5H}MBw2D_OjfmN77@1JJ>lwbCLA4E3#(pvj^)8Fm5jm>qd`Lj1biLU@oZ3fc6&3Q& z6M@rQirJ{d?c$rc&a1)4P(9eb3pWkgZK;Mm9Dn#SzF(J`JJ6|WtA)m;9P;I~QV{C$ z!bTc&W5s#;0(buseO#xH{lm;mBh1Jcyg^6gTOr*Nl@c>@KsMfnmq<^Cj(nvC^R6+y z5sPSKc>o7!kh`X;Z@b;!$gY<&sI_U2w(rf2|V86@~`z^7btG#h-F<)4o(CxL)5{T+-1+H#8EoT)?h$iij%th_qvC|XSORuWt-r{X3z~wS1Mj6v4b5{ms@b|IgWQUy5sPlq0 zleV+BQeAWh89h(qbe#aC&-^T&5iQit#EHY;49xA3T=g}Av$?e%-yoQvY%kleL`I@G ziyHGdTx!d`h&;0j3-m&>im#qf`n5$hm?b&?gO_d5C!2YcX-wQ&r9RAztq$e4 znR^|mUmoTCrxYCuXh1Q3_2iR;en>85Oitln6 zJzTHv%Wgbxc(dH=wY`y00c)e?3LppSS_QuF{*h%pR&i(P-03{lfju&uqHY3epXQkX zEVm%l+`&a5dLK2(Qlw>SWVW|V_J_$V@N&zSP(3^UAgfF)B|^;f*4y#L$gs;cEk+Nl z+0)Q7Kk9dWR&35)#0*L>KtI$v)vadZwNlVS1y>MQRKcf5Q`7a5y^NHApi(K*7{OH!m`KJDf zscYn3fA7MvZQD^EYVsx#cvhG|&CT1mj&CgVQMwMSd{R8c-mO^i4qq>s`e#LF%1sub z9x+uOAJs=hIk_jhn52_lc7;{eL3(}>5?EwFrJHb-HHkxk_s7!(4ZIf(x@+7<#YUe6 z?S_3GBf0Ct<$h>->ZnoHxlRZPg1-siSy&t&@Z|~{AuW zx3<1=m!}nIk-_))h1jts2G-YI(B!Q1Wxcnoqguj{&GkuC^MRXZGBrg6#Hrl(c-=&h z4|_lVuP=Yd5P-9brwz#Y_lG}#s`FCItIiwEx}%TfrSy~a%%zTQO_2>tak*x*Vg$e1|mAw~@=3zSUvq6PpmPVJ2hurCksIz67g>e?HvK7C&)72k8-+_WHd zO@<0zj=EbM{BVBqcv|cCJjKSmL<_+x#Bo>Ve_dEP!yS!v{!MhQ)i< zV$tETN=d|ovSktFVZy>6pSQpR$NX_(6D3^IKsXzWu+WxlLyxgHX z;eL+;%hjM(Zv^E&)n-UtuslEyz0L1o^An2kq-n(-23$ZUI@=g!o9T3hWVOxo>G)$kX)9yWlrj|*CR)BEqypW#Q>e6zj4 zfW-bJB7aNG72{>2o8zSV2}zh@*Ib$@!}T>YXe8s;uzCb*jOt!%);6DIebK*moLkTX zcu|KJ1ziRivD{U4d?zZ@YqHQQ?{JwZ90>VJj_(hexW7s)mJDZ&2%(RwZhZ?h7rgjlEMr zbk45k`|(r3w$92-BH`_UW`&R+cZxs5q_y&7h7U~77ffr`k9YI{YD;KkJ|z$>g#||W z4KHdSZWI!7V}nYhrsWsDR8r{?Ezrk=u)Bu@tC>XPV-{3OvbDqArPiN0+SXz!GnoZ6 zQ35j(NadztENrsU!lM>&WwdC?CVfxZ(8 zr@(0r&?W4L*>^SDReoi56X+d+pOkiR_QV+$7es+Lk7{T`f9QV+&NWb3W5Fkgd zD5Mzmi7gjiGo|kMXqXo%W;AVP|92P=zVoU7?O)p|7A>w>2@RQ9rbY&f{|))bPS%6JEF@ zrumWc^bs*>;r|$dX}@*Ga^@I+RUW@?*#d>iINZ);)O0ft01amyzoiv`za74_#gAwG zV_^u~DpUS~mX^Puq=o~2SfpEoSU}n@;>Sk@6a$%c!I*Z9+LJ90`Vo3guDU5fE;c$u z-N7+=ZVt|2epE9PP6p}16#FYv0p$iqcE;0&R?GgQk4iDqF%J=rFQ$=<-W2*g)08LL z%8omrarg;Rd0(EzhFSdFcy}T@T%6t} zmEv5{D%ahMjK!Nyy-~xUI@162vE}Ys<*ciZ*a^|zkcUCTP0UzY%Vy8=8#&uix=pI7 z!aGGr+(K$C-D9jqX{FNu|Lp$j40hJe;uRhZZS0_T=X|gJ3$Dh{a z=Q&j5CRqk>yi1Xt1sHCAVhepR{G9vQEB|Q5yIuEm8bTe<-21#=P5$hqdUGI5*yP%5 zfVrRC;`LGIHT;yX;7BmL8@9?x{c&6S5gp_k$4&}LgE>+)Ym82-ijV3x@lN&2dm;v4c+<6;8*7RtO9(zN6@t0p z4!+-(To}StM-=Bw!T{@DVX9y1i+sViXuD7~99^{Pu zy|m`@(Z*!sk*+Od!yXrm1w4i7L`6A{=wSDLBzE~ZY0ax5l#c;}9)EnPBSS^lo6bkP zsUke6=ur^iQEX5@C3w`zEo|oJ%Zp;9KUSgVWZYhrE^w}823;w9jF@?3mcLb?(B7eklLi9-vdNdwb8s#lv5 z+S(armYr2nd(L<4rns|lY$X!N?)}0GDKZl28)B=@!p#2LRHd)TZX*mnkSDk3$jD(* zuxugF??SzI0+GVK`8HB{kSNhZfL1nq8&jtgzmWTVy}GwXi7k-2kWDazxD-~Nz#_t- z!OwkasOMX|U?oLmbRVIFSK@pn{EDn~mVQCBw`|DJp_2L?NXrsim(bO>S>)4hDh*%WM*YmbpY9^{>HG_J6W)@N@+=v|529uQ-mDS2`j6#3MDz^AC0k? zxtLLk2>p*OL$tGV7WjiDOlj%j;vm4vY7gn-Ptjj}aImqlvHnq}B>zLe!v<_;{Wsp- z-JQjq^S3_i{QUf^zqx-w&47R799*4jexuBQtRNfEFZ-NX*;&|G|HA$<_HXq6q{S}) z6&Zh?)#FhVFlO@>;g8iVFo&Ze%m5$W(%oucKL1DpUVF?<`2o=5|DAn zY-ZvD5`nx%PG&ZCW)4m*c8IQg0&Hx5O8+PBmjV9>uyZi8@oPcseJWAuMQa|m#=|JnS%K)>3yF|o67HL(DRfb5vHHGjAGchw)Qg3KTm+gUIJJ%NxF zk_bCH&z~**7vn$C5J#K1K&%x}W0!(hD9549$pvZt_sjiD@Ndi?qOQ&$CuTE{IoJ+l zM*bUUXJQKyrj)lcw`kpeK*&MXKd^t*I{XXC`zO-D#L2|M$;83( zFEA$?-=8dZdndEMYS}q>xc{sMT0%sCE)f6yr3yDY5AQGS|C}lWeyQ+J>2Gs>SO4#4 zVt*aLbq2ZodjEf{jrCWYmZWex_Fl)pn;VlS9?^n{vE0oBoswwdu%Bt*S!SmObQq7L zW*Fj3GSrjZ%0e}a;mre{Cev0q9rW9Bhl=&k3v`WXmP(bYx%6hc;9BcwP8Uvdga!5l zE#{)r(Oj6D&?75NKlb&P!?D08#=LsPoz~(cpOv-8Qo8!aN3bpP^)YT5(8FFebt5PU zq!=Edl9`}EYdwIx^W&!#?SS(6LmBjB87ptBeDGdFsZI5B4vA7UyR=Ye&YmfN%;8NT za{3z-DGMD+=R(o;KJM4txE`dO!ngLqNa7f`Pn^6N4h5C_2a0z(@3>c5*S`)V4^f}S zqe+8euD=Zs%sY0l_MrNnWz88big58a&f}3msaE0~ta_OS=VMMRC|qmLdwo){`<64e z!>D9PjgeBQY9a` zmzR=WKvBd=pJ~1sxqVw9z91?pDCq16(9^83cGw&`Etcug5xH2E(!+oT~Y`fg@KBtf*~Z@hKbdbL6^Hj#vi95u<`r}t2T!W zynrKT5Tnz#3>fb8^dsca>NC`tuv+uGc|o?dxU1^mE&a>!SUsjx6SwSzUNg_jF^MB4jw3_FOGthk+~Rh%#r~I04X+QgwzQ-vsp2>B{=8sgcQ( z$`%H1D*0g?PL(w$i(1BWF!l4hnbHr^M4b?uj8iIol zWQyDC&A&}H(em~^Z)@Y?RF;%Rr}9SYNIM4m*8D^l63xf$H&0w)VLU3Xpqn|)p+3Ux z4@OaFXdFjw%$?bGD>9vNn~hm<^HQAURvgk^BoH1NU_3I!65|HHV)*V$VB75eE-PX3 z^4>{hdV3r$EV;AZKzIU~=G^HsL!&j)Xw^>1cuH=&+Rd&-=&Y9x7cWOm8t?l&#U|@d z3W`JANkqC$EMFNt8=5qy50p+)&tFvR`i|767_KT%3ul}AEH%f}tW*`HVlM(}%t|iR z1)iP{*ILsg)B++f%KX-dmLFpE%cXiJ7D3oaOa;alD72Monnh;ol=I=KPYWxw!KGm(;I6FD=J68 z*kJaw@ARkX*0rBfHboGBlc}%CnoAJp)cQPQPDv7;rJCeu|AHzNTyV*4lKrxA!378vDF~n zxf%c_H?qZO@3?-5?hhz^g83CBt4_bdt%ZcaCXijw|9zf+1)1lSrM1MF{Fk9=nU+O^qCklXH&Hx|H7baD_#k%$v9B>-}{Y{Tn-v zwp8Te%Z+C4+NG~b$H*`*eOW}pTEECF`vnDT&@+DuLF@#{ye48BXjdeC5NC=I-CLnt{-_C8YxkX<#FQIZO< z2na~#7@ zBG^QccH>U7d&|z!q}cA+`p)Q=SBJPrHn1VLNi<-8c@-K42kL*nzyfjYztX?2v-~Cb z*KL%4?^gf1jq*>jg^>TcoATd+|6U3G+RXkZSrGqwYx^&`U;JNpZT@?m^pBhr?LVug zzoh6tQ* literal 0 HcmV?d00001 diff --git a/doc/salome/Makefile.in b/doc/salome/Makefile.in new file mode 100644 index 000000000..15dbc9285 --- /dev/null +++ b/doc/salome/Makefile.in @@ -0,0 +1,44 @@ + +# -* Makefile *- +# +# Author : Patrick GOLDBRONN (CEA) +# Date : 30/11/2001 +# $Header$ +# +# source path +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@ + +SUBDIRS= tui gui + +@COMMENCE@ + +docs: + @@SETX@; for d in $(SUBDIRS); do \ + (cd $$d && $(MAKE) $@) || exit 1; \ + done; \ + cp -f $(srcdir)/SMESH_index.html SMESH_index.html + +clean: + @@SETX@; for d in $(SUBDIRS); do \ + (cd $$d && $(MAKE) $@) || exit 1; \ + done + +distclean: clean + @@SETX@; for d in $(SUBDIRS); do \ + (cd $$d && $(MAKE) $@) || exit 1; \ + done + +install: + $(MAKE) docs + (cd tui && $(MAKE) install); + (cd gui && $(MAKE) install); + cp -f SMESH_index.html $(docdir) + +uninstall: + @@SETX@; for d in $(SUBDIRS); do \ + (cd $$d && $(MAKE) $@) || exit 1; \ + done; \ + rm -fr $(docdir)/SMESH_index.html diff --git a/doc/salome/PluginMeshers.txt b/doc/salome/PluginMeshers.txt new file mode 100644 index 000000000..61bb0842b --- /dev/null +++ b/doc/salome/PluginMeshers.txt @@ -0,0 +1,188 @@ +####################################################################################### +# File : PluginMeshers.txt +# Author : Julia DOROVSKIKH +# Module : SMESH +# $Header$ +####################################################################################### +# +# How to add your own mesher (as a set of hypotheses and algorithms) to the application +# +####################################################################################### + +1. Create mesher plugin package, e.g. MyMesher. + +2. Create XML file to describe all algorithms and hypotheses, provided by plugin package + (see SMESH_SRC/resources/SMESH_Meshers.xml for example). + + + + + + + + + + + Attributes of tag: + + - value of attribute is used to collect hypotheses/algoritms in groups; + you can also use this attribute for short description of your mesher plugin + + - value of attribute (MyResourceKey) is used to access resources + (messages and icons) from GUI (see paragraphs 4.2 and 5); + currently it should coincide with the name of plugin package; this limitation + will be eliminated in the further development. + + - value of attribute describes the name of your mesher's + server plugin library (See paragraph 3) + + - value of attribute describes the name of your mesher's + client plugin library (See paragraph 4) + + Attributes of tag: + + - value of attribute is an unique name of the hypothesis/algorithm + + * It is a value of _name field of your hypothesis class + (see paragraph 3, implementation of constructor of + StdMeshers_LocalLength class: _name = "LocalLength") + + * It is a key to each certain hypothesis class + (see paragraph 3, implementation of "GetHypothesisCreator()" method in StdMeshers_i.cxx) + + * It is a key to each certain hypothesis GUI + (see paragraph 4, implementation of "StdMeshersGUI_HypothesisCreator::CreateHypothesis()" + and "StdMeshersGUI_HypothesisCreator::EditHypothesis()" methods in StdMeshersGUI.cxx) + + * It is a key to each certain hypothesis icon in Object Browser + (see paragraph 4.2.1) + + - value of attribute is displayed in the GUI in the list + of available hypotheses/algorithms ("Create Hypothesis/Algorithm" dialog) + + - value of attribute is a name of icon file, which is displayed in GUI + in the list of available hypotheses/algorithms ("Create Hypothesis/Algorithm" dialog) + + Note: All attributes values are accessible in your GUI via HypothesisData class + (see paragraph 4.1) + + Note: The environment variable SMESH_MeshersList contains the list of plugins names, + separated by colon (":") symbol, e.g.: + + setenv SMESH_MeshersList StdMeshers:NETGENPlugin + + Please, pay attention that StdMeshers should also be included into this environment variable, + if you want to use standard hypotheses/algorithms, provided with SMESH module. + + The SALOME automatically locates XML files, searching them in the following directories: + + ${_ROOT_DIR}/share/salome/resources + ${SALOME_Resources} + ${HOME}/.salome/resources + ${KERNEL_ROOT_DIR}/share/salome/resources + + where is a name of each mesher plugin package + +3. Build server plugin library . + + 3.1. Define interface to your hypotheses and algorithms. + + Example: SMESH_SRC/idl/SMESH_BasicHypothesis.idl + NETGENPLUGIN_SRC/src/NETGENPlugin_Algorithm.idl + + 3.2. Implement functionality of your hypotheses and algorithms. + Inherit corresponding classes from SMESH. + + Example: SMESH_SRC/src/StdMeshers/StdMeshers_* + NETGENPLUGIN_SRC/src/NETGENPlugin_NETGEN_3D + + 3.3. Implement interface to your hypotheses and algorithms. + Inherit corresponding classes from SMESH_I. + + Example: SMESH_SRC/src/StdMeshers_I/SMESH_*_i + NETGENPLUGIN_SRC/src/NETGENPlugin_NETGEN_3D_i + + 3.4. Implement being exported method. + + GenericHypothesisCreator_i* GetHypothesisCreator (const char* aHypType) + + is a value of attribute in the XML-description file + + Example: SMESH_SRC/src/StdMeshers_I/StdMeshers_i.cxx + NETGENPLUGIN_SRC/src/NETGENPlugin_i.cxx + +4. Build client (GUI) plugin library . + This step is required only if your hypotheses/algorithms need specific GUI for their construction. + + 4.1. Implement the required GUI (e.g. construction dialog boxes). + + Example: SMESH_SRC/src/StdMeshersGUI/StdMeshersGUI_*Dlg + + Note: all data from XML-description files is accessible in your GUI via HypothesisData class + (mySMESHGUI->GetHypothesisData (aHypType), + see SMESHGUI_Hypotheses.h for HypothesisData definition) + + 4.2. Provide icons and messages for your GUI. + + 4.2.1. Implement resource files + MyResourceKey_icons.po and MyResourceKey_msg_en.po + + Example: SMESH_SRC/src/StdMeshersGUI/StdMeshers_*.po + NETGENPLUGIN_SRC/src/NETGENPlugin_icons.po + + Note: ICON_SMESH_TREE_HYPO_MyHypType1 is ID of icon for Object Browser + for hypothesis with type="MyHypType1". + + ICON_SMESH_TREE_ALGO_MyAlgType1 is ID of icon for Object Browser + for algorithm with type="MyAlgType1". + + See paragraph 2 for definition of MyResourceKey, MyHypType1, MyAlgType1. + + 4.2.2. Define environment variable SALOME_Resources to point to the + directory where resources are situated. + + Example: setenv SALOME_StdMeshersResources ${SMESH_ROOT_DIR}/share/salome/resources + + 4.3. Implement your Hypothesis Creator and being exported method + + SMESHGUI_GenericHypothesisCreator* GetHypothesisCreator + (QString aHypType, QString aServerLibName, SMESHGUI* aSMESHGUI) + + is to pass a value of attribute in XML-description file; + is to pass a value of attribute in XML-description file. + + Example: SMESH_SRC/src/StdMeshersGUI/StdMeshersGUI.cxx + +5. If your hypotheses/algorithms do not need specific GUI, + but you want to provide icons for object browser, see 4.2 paragrath + +6. Setup your SALOME environment. + + 6.1. Add your plugin to the LD_LIBRARY_PATH, PYTHONPATH (and maybe PATH) environment variables, e.g.: + + setenv PATH /bin/salome:${PATH} + setenv LD_LIBRARY_PATH /lib/salome:${LD_LIBRARY_PATH} + setenv PYTHONPATH /lib/python2.2/site-packages/salome:${PYTHONPATH} + + 6.2. Set mesher plugin resources environment variable (see 4.2.2 paragraph) + +Note: If you use runSalome.py script from KERNEL package to launch SALOME, you may not to set + environment variables, because this script sets them itself. All what you should do is + to add section to your ${HOME}/.salome/salome.launch file for SMESH module section: + + ... + + ... + + + + ... + + ... \ No newline at end of file diff --git a/doc/salome/SMESH_index.html b/doc/salome/SMESH_index.html new file mode 100644 index 000000000..585ce9e7e --- /dev/null +++ b/doc/salome/SMESH_index.html @@ -0,0 +1,95 @@ + + + + + + + + Mesh Module Documentation + + + +
  +
+
                   +   
+ + + + + + + + + +
+ + + +
+ +
+
+
+

Mesh MODULE Documentation

+
+
+ + + + + +
+
+ +
+

Application-About.png +     

+
+ +
+ + + + +
+
+
+
+
+ +
+ +
GUI Documentation
+ +
+ +
+ +

+
+ +
+ +
TUI Documentation
+ +
+ +
+ +

+
+
+
+
+
+
+ + diff --git a/doc/salome/gui/Makefile.in b/doc/salome/gui/Makefile.in new file mode 100644 index 000000000..883a053da --- /dev/null +++ b/doc/salome/gui/Makefile.in @@ -0,0 +1,33 @@ +# Copyright (C) 2003 CEA/DEN, EDF R&D +# +# +# +# File : Makefile.in +# Author : Vasily Rusyaev (Open Cascade NN) +# Module : doc +# $Header: + +top_srcdir=@top_srcdir@ +top_builddir=../../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@ + +@COMMENCE@ + +docs: + cp -fr $(srcdir)/SMESH ./ + -find $(PWD) -name CVS -exec rm -rf {} \; + +clean: + rm -fr `ls | grep -v "Makefile"` + +distclean: clean + rm -fr SMESH + +install: + mkdir -p $(docdir)/gui + cp -rf SMESH $(docdir)/gui + -find $(PWD) -name CVS -exec rm -rf {} \; + +uninstall: + rm -rf $(docdir)/gui/SMESH diff --git a/idl/Makefile.in b/idl/Makefile.in index c53a07895..40a4c84f2 100644 --- a/idl/Makefile.in +++ b/idl/Makefile.in @@ -6,7 +6,7 @@ top_srcdir=@top_srcdir@ top_builddir=.. srcdir=@srcdir@ -VPATH=.:$(srcdir):${KERNEL_ROOT_DIR}/idl/salome:${GEOM_ROOT_DIR}/idl/salome:${MED_ROOT_DIR}/idl/salome +VPATH=.:${KERNEL_ROOT_DIR}/idl/salome:${GEOM_ROOT_DIR}/idl/salome:${MED_ROOT_DIR}/idl/salome @COMMENCE@ @@ -14,16 +14,21 @@ IDL_FILES = \ SMESH_Gen.idl \ SMESH_Mesh.idl \ SMESH_Hypothesis.idl \ - SMESH_BasicHypothesis.idl + SMESH_BasicHypothesis.idl \ + SMESH_Filter.idl \ + SMESH_Group.idl PY_CLIENT_IDL = $(IDL_FILES) # we copy all idl file in $(top_builddir)/idl -inc: $(IDL_FILES:%=$(top_builddir)/idl/%) +inc: $(top_builddir)/idl/salome $(IDL_FILES:%=$(top_builddir)/idl/salome/%) -$(IDL_FILES:%=$(top_builddir)/idl/%):$(top_builddir)/idl/%:% +$(top_builddir)/idl/salome: + mkdir $@ + +$(IDL_FILES:%=$(top_builddir)/idl/salome/%):$(IDL_FILES:%=$(top_srcdir)/idl/%) # $(CP) $< $@ - cp -f $< $@ + cp -f $^ $(top_builddir)/idl/salome lib: pyidl @@ -35,7 +40,7 @@ pyidl: $(PYTHON_BUILD_SITE) $(IDL_FILES:%.idl=$(PYTHON_BUILD_SITE)/%_idl.py) $(PYTHON_BUILD_SITE): $(INSTALL) -d $@ -$(PYTHON_BUILD_SITE)/%_idl.py: %.idl +$(PYTHON_BUILD_SITE)/%_idl.py: $(top_builddir)/idl/salome/%.idl $(OMNIORB_IDL) $(OMNIORB_IDLPYFLAGS) -C$(PYTHON_BUILD_SITE) $< @@ -43,12 +48,12 @@ $(PYTHON_BUILD_SITE)/%_idl.py: %.idl install: install-pyidl install-idl # create directory $(idldir) and copy idl files into it -install-idl: $(IDL_FILES) +install-idl: $(IDL_FILES:%=$(top_builddir)/idl/salome/%) $(INSTALL) -d $(idldir) $(INSTALL_DATA) $^ $(idldir) -install-pyidl: $(IDL_FILES) +install-pyidl: $(IDL_FILES:%=$(top_builddir)/idl/salome/%) $(INSTALL) -d $(PYTHON_SITE_INSTALL) @for file in $^ dummy; do \ if [ $$file != "dummy" ]; then \ @@ -63,6 +68,6 @@ cleandep: distclean: -$(RM) *.py - -$(RM) $(IDL_FILES:%=$(top_builddir)/idl/%) + -$(RM) $(IDL_FILES:%=$(top_builddir)/idl/salome/%) -$(RM) Makefile diff --git a/idl/SMESH_BasicHypothesis.idl b/idl/SMESH_BasicHypothesis.idl index f6a37655c..9987c2c44 100644 --- a/idl/SMESH_BasicHypothesis.idl +++ b/idl/SMESH_BasicHypothesis.idl @@ -30,67 +30,142 @@ #include "SMESH_Hypothesis.idl" -module SMESH +/*! + * StdMeshers: interfaces to standard hypotheses and algorithms + */ +module StdMeshers { - interface SMESH_LocalLength : SMESH_Hypothesis + /*! + * StdMeshers_LocalLength: interface of "Average length" hypothesis + */ + interface StdMeshers_LocalLength : SMESH::SMESH_Hypothesis { + /*! + * Sets parameter value + */ void SetLength(in double length) raises (SALOME::SALOME_Exception); + + /*! + * Returns parameter value + */ double GetLength(); }; - interface SMESH_NumberOfSegments : SMESH_Hypothesis + /*! + * StdMeshers_NumberOfSegments: interface of "Nb. Segments" hypothesis + */ + interface StdMeshers_NumberOfSegments : SMESH::SMESH_Hypothesis { + /*! + * Sets parameter value + */ void SetNumberOfSegments(in long segmentsNumber) raises (SALOME::SALOME_Exception); + + /*! + * Returns parameter value + */ long GetNumberOfSegments(); + + /*! + * Sets parameter value + */ void SetScaleFactor(in double scaleFactor) raises (SALOME::SALOME_Exception); + + /*! + * Returns parameter value + */ double GetScaleFactor(); }; - interface SMESH_MaxElementArea : SMESH_Hypothesis + /*! + * StdMeshers_MaxElementArea: interface of "Max. Triangle Area" hypothesis + */ + interface StdMeshers_MaxElementArea : SMESH::SMESH_Hypothesis { + /*! + * Sets parameter value + */ void SetMaxElementArea(in double area) raises (SALOME::SALOME_Exception); + + /*! + * Returns parameter value + */ double GetMaxElementArea(); }; - interface SMESH_LengthFromEdges : SMESH_Hypothesis + /*! + * StdMeshers_LengthFromEdges: interface of "Length From Edges (2D Hyp. for Triangulator)" hypothesis + */ + interface StdMeshers_LengthFromEdges : SMESH::SMESH_Hypothesis { + /*! + * Sets parameter value + */ void SetMode(in long mode) raises (SALOME::SALOME_Exception); + + /*! + * Returns parameter value + */ long GetMode(); }; - interface SMESH_MaxElementVolume : SMESH_Hypothesis + /*! + * StdMeshers_MaxElementVolume: interface of "Max. Hexahedron or Tetrahedron Volume" hypothesis + */ + interface StdMeshers_MaxElementVolume : SMESH::SMESH_Hypothesis { + /*! + * Sets parameter value + */ void SetMaxElementVolume(in double volume) raises (SALOME::SALOME_Exception); + + /*! + * Returns parameter value + */ double GetMaxElementVolume(); }; - interface SMESH_Regular_1D : SMESH_1D_Algo + /*! + * StdMeshers_NotConformAllowed: interface of "Not Conform Mesh Allowed" hypothesis. + * Presence of this hypothesis permits to algorithm generation of not conform mesh. + */ + interface StdMeshers_NotConformAllowed : SMESH::SMESH_Hypothesis { }; - interface SMESH_MEFISTO_2D : SMESH_2D_Algo + /*! + * StdMeshers_Regular_1D: interface of "Wire discretisation" algorithm + */ + interface StdMeshers_Regular_1D : SMESH::SMESH_1D_Algo { }; - interface SMESH_Quadrangle_2D : SMESH_2D_Algo + /*! + * StdMeshers_MEFISTO_2D: interface of "Triangle (Mefisto)" algorithm + */ + interface StdMeshers_MEFISTO_2D : SMESH::SMESH_2D_Algo { }; - interface SMESH_Hexa_3D : SMESH_3D_Algo + /*! + * StdMeshers_Quadrangle_2D: interface of "Quadrangle (Mapping)" algorithm + */ + interface StdMeshers_Quadrangle_2D : SMESH::SMESH_2D_Algo { }; -#ifdef HAVE_NETGEN - interface SMESH_NETGEN_3D : SMESH_3D_Algo + /*! + * StdMeshers_Hexa_3D: interface of "Hexahedron (i,j,k)" algorithm + */ + interface StdMeshers_Hexa_3D : SMESH::SMESH_3D_Algo { }; -#endif }; diff --git a/idl/SMESH_Filter.idl b/idl/SMESH_Filter.idl new file mode 100644 index 000000000..e0a5d7739 --- /dev/null +++ b/idl/SMESH_Filter.idl @@ -0,0 +1,110 @@ +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_Filter.idl +// Author : Alexey Petrov, OCC + +#ifndef _SMESH_FILTER_IDL_ +#define _SMESH_FILTER_IDL_ + +#include "SALOME_Exception.idl" +#include "SALOME_GenericObj.idl" +#include "SMESH_Mesh.idl" + +module SMESH{ + + interface Functor: SALOME::GenericObj{ + void SetMesh(in SMESH_Mesh theMesh); + }; + + interface NumericalFunctor: Functor{ + double GetValue(in long theElementId); + }; + + interface MinimumAngle: NumericalFunctor{}; + interface AspectRatio: NumericalFunctor{}; + interface Warping: NumericalFunctor{}; + interface Taper: NumericalFunctor{}; + interface Skew: NumericalFunctor{}; + interface Area: NumericalFunctor{}; + interface Length: NumericalFunctor{}; + interface MultiConnection: NumericalFunctor{}; + + interface Predicate: Functor{ + boolean IsSatisfy(in long thEntityId); + }; + + interface FreeBorders: Predicate{}; + + interface Comparator: Predicate{ + void SetMargin(in double theValue); + void SetNumFunctor(in NumericalFunctor theFunct); + }; + + interface LessThan: Comparator{}; + interface MoreThan: Comparator{}; + interface EqualTo: Comparator{ + void SetTolerance(in double theTolerance ); + }; + + interface Logical: Predicate{}; + + interface LogicalNOT: Logical{ + void SetPredicate(in Predicate thePredicate); + }; + + interface LogicalBinary: Logical{ + void SetPredicate1(in Predicate thePredicate); + void SetPredicate2(in Predicate thePredicate); + }; + + interface LogicalAND: LogicalBinary{}; + interface LogicalOR: LogicalBinary{}; + interface Filter: SALOME::GenericObj{ + void SetPredicate( in Predicate thePredicate ); + long_array GetElementsId( in SMESH_Mesh theMesh ); + }; + + interface FilterManager: SALOME::GenericObj{ + MinimumAngle CreateMinimumAngle(); + AspectRatio CreateAspectRatio(); + Warping CreateWarping(); + Taper CreateTaper(); + Skew CreateSkew(); + Area CreateArea(); + Length CreateLength(); + MultiConnection CreateMultiConnection(); + + FreeBorders CreateFreeBorders(); + + LessThan CreateLessThan(); + MoreThan CreateMoreThan(); + EqualTo CreateEqualTo(); + + LogicalNOT CreateLogicalNOT(); + LogicalAND CreateLogicalAND(); + LogicalOR CreateLogicalOR(); + Filter CreateFilter(); + }; + +}; + +#endif diff --git a/idl/SMESH_Gen.idl b/idl/SMESH_Gen.idl index 82136fee1..390813d48 100644 --- a/idl/SMESH_Gen.idl +++ b/idl/SMESH_Gen.idl @@ -39,19 +39,35 @@ module SMESH { typedef sequence shape_array; + typedef sequence mesh_array; + + interface FilterManager; interface SMESH_Gen : Engines::Component, SALOMEDS::Driver { + + FilterManager CreateFilterManager(); + /*! - * Create an hypothesis that can be shared by differents parts of the mesh. + Set the current study + */ + void SetCurrentStudy( in SALOMEDS::Study theStudy ); + + /*! + Get the current study + */ + SALOMEDS::Study GetCurrentStudy(); + + /*! + * Create a hypothesis that can be shared by differents parts of the mesh. * An hypothesis is either: * - a method used to generate or modify a part of the mesh (algorithm). * - a parameter or a law used by an algorithm. * Algorithms are 1D, 2D or 3D. */ - SMESH_Hypothesis CreateHypothesis( in string anHyp, - in long studyId) - raises (SALOME::SALOME_Exception); + SMESH_Hypothesis CreateHypothesis( in string theHypName, + in string theLibName ) + raises ( SALOME::SALOME_Exception ); /*! * Create a Mesh object, given a geometry shape. @@ -60,57 +76,53 @@ module SMESH * of TopoDS_Shapes and bind CORBA references of shape & subshapes * with TopoDS_Shapes */ - SMESH_Mesh Init(in GEOM::GEOM_Gen geomEngine, - in long studyId, - in GEOM::GEOM_Shape aShape) - raises (SALOME::SALOME_Exception); + SMESH_Mesh CreateMesh( in GEOM::GEOM_Shape theShape ) + raises ( SALOME::SALOME_Exception ); + + /*! + * Create Mesh object(s) importing data from given MED file + */ + mesh_array CreateMeshesFromMED( in string theFileName, + out SMESH::DriverMED_ReadStatus theStatus ) + raises ( SALOME::SALOME_Exception ); /*! * Create a Mesh object, without a geometry shape reference */ -// SMESH_Mesh NewEmpty(in GEOM::GEOM_Gen geomEngine, -// in long studyId) -// raises (SALOME::SALOME_Exception); +// SMESH_Mesh NewEmpty() +// raises ( SALOME::SALOME_Exception ); /*! * Mesh a subShape. * First, verify list of hypothesis associated with the subShape, * return NOK if hypothesis are not sufficient */ - boolean Compute(in SMESH_Mesh aMesh, in GEOM::GEOM_Shape aSubShape) - raises (SALOME::SALOME_Exception); + boolean Compute( in SMESH_Mesh theMesh, + in GEOM::GEOM_Shape theSubShape ) + raises ( SALOME::SALOME_Exception ); /*! * */ - boolean IsReadyToCompute(in SMESH_Mesh aMesh, in GEOM::GEOM_Shape aSubShape) - raises (SALOME::SALOME_Exception); + boolean IsReadyToCompute( in SMESH_Mesh theMesh, + in GEOM::GEOM_Shape theSubShape ) + raises ( SALOME::SALOME_Exception ); /*! * */ - long_array GetSubShapesId(in GEOM::GEOM_Gen geomEngine, - in long studyId, - in GEOM::GEOM_Shape mainShape, - in shape_array listOfSubShape) - raises (SALOME::SALOME_Exception); + long_array GetSubShapesId( in GEOM::GEOM_Shape theMainShape, + in shape_array theListOfSubShape ) + raises ( SALOME::SALOME_Exception ); /*! * */ - // long_array GetSubMeshesState(in GEOM::GEOM_Gen geomEngine, - // in long studyId, - // in shape_array listOfSubShape) - // raises (SALOME::SALOME_Exception); + // long_array GetSubMeshesState( in shape_array theListOfSubShape ) + // raises ( SALOME::SALOME_Exception ); - /** - * Import a mesh from a file. - * @param fileName file name to be imported. - * @param fileType Currently it could be either "DAT", "UNV" or "MED". - * @param studyId The id of the current study. - */ - SMESH_Mesh Import(in long studyId, in string fileName, in string fileType); + }; }; diff --git a/idl/SMESH_Group.idl b/idl/SMESH_Group.idl new file mode 100644 index 000000000..9842df2f6 --- /dev/null +++ b/idl/SMESH_Group.idl @@ -0,0 +1,103 @@ +// Copyright (C) 2004 CEA +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_Group.idl +// Author : Sergey ANIKIN, OCC +// $Header$ + +#ifndef _SMESH_GROUP_IDL_ +#define _SMESH_GROUP_IDL_ + +#include "SALOME_Exception.idl" +#include "SALOME_GenericObj.idl" + +#include "SMESH_Mesh.idl" + +module SMESH +{ + /*! + * SMESH_Group: interface of group object + */ + interface SMESH_Group : SALOME::GenericObj + { + /*! + * Sets group name + */ + void SetName( in string name ); + + /*! + * Returns group name + */ + string GetName(); + + /*! + * Returns group type (type of elements in the group) + */ + ElementType GetType(); + + /*! + * Returns the number of elements in the group + */ + long Size(); + + /*! + * Returns true if the group does not contain any elements + */ + boolean IsEmpty(); + + /*! + * Clears the group's contents + */ + void Clear(); + + /*! + * returns true if the group contains an element with ID == + */ + boolean Contains( in long elem_id ); + + /*! + * Adds elements to the group + */ + long Add( in long_array elem_ids ); + + /*! + * Returns ID of an element at position + */ + long GetID( in long elem_index ); + + /*! + * Returns a sequence of all element IDs in the group + */ + long_array GetListOfID(); + + /*! + * Removes elements from the group + */ + long Remove( in long_array elem_ids ); + + /*! + * Returns the mesh object this group belongs to + */ + SMESH_Mesh GetMesh(); + }; +}; + + +#endif diff --git a/idl/SMESH_Hypothesis.idl b/idl/SMESH_Hypothesis.idl index e3e82b80c..6389d724f 100644 --- a/idl/SMESH_Hypothesis.idl +++ b/idl/SMESH_Hypothesis.idl @@ -27,26 +27,29 @@ #define _SMESH_HYPOTHESIS_IDL_ #include "SALOME_Exception.idl" +#include "SALOME_GenericObj.idl" module SMESH { - interface SMESH_Hypothesis; - - typedef sequence ListOfHypothesis; - typedef sequence ListOfHypothesisName; - - interface SMESH_Hypothesis + interface SMESH_Hypothesis : SALOME::GenericObj { /*! * Get the Hypothesis typeName */ string GetName(); + /*! + * Get the Hypothesis plugin library Name + */ + string GetLibName(); + /*! * Get the internal Id */ long GetId(); - }; + }; + + typedef sequence ListOfHypothesisName; interface SMESH_Algo : SMESH_Hypothesis { diff --git a/idl/SMESH_Mesh.idl b/idl/SMESH_Mesh.idl index b2c5813b5..b81acf6a0 100644 --- a/idl/SMESH_Mesh.idl +++ b/idl/SMESH_Mesh.idl @@ -27,13 +27,30 @@ #define _SMESH_MESH_IDL_ #include "SALOME_Exception.idl" -#include "SMESH_Hypothesis.idl" +//#include "SMESH_Hypothesis.idl" + +#include "SALOME_GenericObj.idl" +//#include "GEOM_Shape.idl" +//#include "MED.idl" + +module GEOM +{ + interface GEOM_Shape; +}; + + +module SALOME_MED +{ + interface MESH; + interface FAMILY; +}; -#include "GEOM_Shape.idl" -#include "MED.idl" module SMESH { + interface SMESH_Hypothesis; + typedef sequence ListOfHypothesis; + typedef sequence double_array ; typedef sequence long_array ; typedef sequence string_array ; @@ -49,8 +66,7 @@ module SMESH ADD_PRISM, ADD_HEXAHEDRON, REMOVE_NODE, - REMOVE_ELEMENT, - REMOVE_ALL + REMOVE_ELEMENT }; struct log_block @@ -60,12 +76,56 @@ module SMESH double_array coords; long_array indexes; }; + + /*! + * Enumeration for element type, like in SMDS + */ + enum ElementType + { + ALL, + NODE, + EDGE, + FACE, + VOLUME + }; + + /*! + * Enumeration for hypothesis status (used by AddHypothesis() and RemoveHypothesis() methods) + */ + enum Hypothesis_Status // in the order of severity + { + HYP_OK, + HYP_MISSING, // algo misses a hypothesis + HYP_CONCURENT, // several applicable hypotheses + HYP_BAD_PARAMETER,// hypothesis has a bad parameter value + HYP_UNKNOWN_FATAL,// --- all statuses below should be considered as fatal + // for Add/RemoveHypothesis operations + HYP_INCOMPATIBLE, // hypothesis does not fit algo + HYP_NOTCONFORM, // not conform mesh is produced appling a hypothesis + HYP_ALREADY_EXIST,// such hypothesis already exist + HYP_BAD_DIM // bad dimension + }; + + /*! + * Enumeration for DriverMED read status (used by ImportMEDFile() method) + */ + enum DriverMED_ReadStatus // in the order of severity + { + DRS_OK, + DRS_EMPTY, // a MED file contains no mesh with the given name + DRS_WARN_RENUMBER, // a MED file has overlapped ranges of element numbers, + // so the numbers from the file are ignored + DRS_WARN_SKIP_ELEM, // some elements were skipped due to incorrect file data + DRS_FAIL // general failure (exception etc.) + }; + typedef sequence log_array; + interface SMESH_Group; interface SMESH_subMesh; interface SMESH_MeshEditor; - interface SMESH_Mesh + interface SMESH_Mesh : SALOME::GenericObj { /*! * Associate a Shape to a Mesh created with NewEmpty @@ -80,7 +140,7 @@ module SMESH * SubMesh will be used instead of SubShape in a next idl version to * adress a specific subMesh... */ - SMESH_subMesh GetElementsOnShape(in GEOM::GEOM_Shape aSubShape) + SMESH_subMesh GetSubMesh(in GEOM::GEOM_Shape aSubShape, in string name) raises (SALOME::SALOME_Exception); /*! @@ -89,6 +149,25 @@ module SMESH // SMESH_subMesh NewEmpty() // raises (SALOME::SALOME_Exception); + /*! + * Remove a submesh + */ + void RemoveSubMesh(in SMESH_subMesh aSubMesh) + raises (SALOME::SALOME_Exception); + + /*! + * Create a group + */ + SMESH_Group CreateGroup( in ElementType elem_type, + in string name ) + raises (SALOME::SALOME_Exception); + + /*! + * Remove a group + */ + void RemoveGroup(in SMESH_Group aGroup) + raises (SALOME::SALOME_Exception); + /*! * Add hypothesis to the mesh, under a particular subShape * (or the main shape itself) @@ -106,7 +185,8 @@ module SMESH * (or one previous hypothesis on the subShape) * raises exception if hypothesis has not been created */ - boolean AddHypothesis(in GEOM::GEOM_Shape aSubShape, in SMESH_Hypothesis anHyp) + Hypothesis_Status AddHypothesis(in GEOM::GEOM_Shape aSubShape, + in SMESH_Hypothesis anHyp) raises (SALOME::SALOME_Exception); // boolean AddHypothesis(in SMESH_subMesh aSubMesh, in SMESH_Hypothesis anHyp) // raises (SALOME::SALOME_Exception); @@ -115,8 +195,8 @@ module SMESH /*! * Remove an hypothesis previouly added with AddHypothesis. */ - boolean RemoveHypothesis(in GEOM::GEOM_Shape aSubShape, - in SMESH_Hypothesis anHyp) + Hypothesis_Status RemoveHypothesis(in GEOM::GEOM_Shape aSubShape, + in SMESH_Hypothesis anHyp) raises (SALOME::SALOME_Exception); // boolean RemoveHypothesis(in SMESH_subMesh aSubMesh, // in SMESH_Hypothesis anHyp) @@ -162,11 +242,13 @@ module SMESH raises (SALOME::SALOME_Exception); /*! - * Export mesh to a file - * @param fileName file name where to export the file - * @param fileType Currently it could be either "DAT", "UNV" or "MED". + * Export Mesh with DAT and MED Formats */ - void Export( in string fileName, in string fileType ) + void ExportDAT( in string file ) + raises (SALOME::SALOME_Exception); + void ExportMED( in string file, in boolean auto_groups ) + raises (SALOME::SALOME_Exception); + void ExportUNV( in string file ) raises (SALOME::SALOME_Exception); /*! @@ -199,11 +281,19 @@ module SMESH long NbHexas() raises (SALOME::SALOME_Exception); + long NbPyramids() + raises (SALOME::SALOME_Exception); + + long NbPrisms() + raises (SALOME::SALOME_Exception); + long NbSubMesh() raises (SALOME::SALOME_Exception); + + string Dump(); }; - interface SMESH_subMesh + interface SMESH_subMesh : SALOME::GenericObj { /*! * @@ -223,6 +313,12 @@ module SMESH long_array GetElementsId() raises (SALOME::SALOME_Exception); + /*! + * + */ + long_array GetElementsByType( in ElementType theType ) + raises (SALOME::SALOME_Exception); + /*! * */ diff --git a/idl/SMESH_NetgenAlgorithm.idl b/idl/SMESH_NetgenAlgorithm.idl new file mode 100644 index 000000000..afe23ad72 --- /dev/null +++ b/idl/SMESH_NetgenAlgorithm.idl @@ -0,0 +1,45 @@ +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_NetgenAlgorithm.idl +// Author : Julia DOROVSKIKH +// $Header$ + +#ifndef _SMESH_NETGENALGORITHM_IDL_ +#define _SMESH_NETGENALGORITHM_IDL_ + +#include "SMESH_Hypothesis.idl" + +/*! + * NETGENPlugin: interfaces to NETGEN related hypotheses and algorithms + */ +module NETGENPlugin +{ + /*! + * NETGENPlugin_NETGEN_3D: interface of "Tetrahedron (Netgen)" algorithm + */ + interface NETGENPlugin_NETGEN_3D : SMESH::SMESH_3D_Algo + { + }; + +}; + +#endif diff --git a/resources/SMESH.config b/resources/SMESH.config new file mode 100644 index 000000000..ec675575a --- /dev/null +++ b/resources/SMESH.config @@ -0,0 +1,2 @@ +language=en +resources=StdMeshers:NETGENPlugin \ No newline at end of file diff --git a/resources/SMESH_Meshers.xml b/resources/SMESH_Meshers.xml new file mode 100644 index 000000000..49aae9d0d --- /dev/null +++ b/resources/SMESH_Meshers.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/SMESH_MeshersWithNETGEN.xml b/resources/SMESH_MeshersWithNETGEN.xml new file mode 100644 index 000000000..2952c9279 --- /dev/null +++ b/resources/SMESH_MeshersWithNETGEN.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/SMESH_en.xml b/resources/SMESH_en.xml index e1bb694bf..449962659 100644 --- a/resources/SMESH_en.xml +++ b/resources/SMESH_en.xml @@ -17,7 +17,7 @@ - + @@ -37,37 +37,34 @@ - - - - - - - - - - - + + - - - + + + + + + + - + + + - - + + @@ -90,30 +87,28 @@ - - - - - - - - + + - - - + + + + + - + - + + + @@ -121,12 +116,6 @@ - - - - - - @@ -134,83 +123,210 @@ - + + + + + - - + + + - + + + + + + + + + + + + + + + + + + + - + + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + - - - - - - - - - - - + + - + + + @@ -233,16 +349,12 @@ - - + + - - - - diff --git a/resources/SMESH_fr.xml b/resources/SMESH_fr.xml index 5c29ab6ec..bef8ea89f 100644 --- a/resources/SMESH_fr.xml +++ b/resources/SMESH_fr.xml @@ -17,7 +17,7 @@ - + @@ -37,17 +37,8 @@ - - - - - - - - - - - + + @@ -58,6 +49,8 @@ + + @@ -90,8 +83,8 @@ - - + + @@ -111,7 +104,7 @@ - + @@ -139,11 +132,15 @@ + + + + @@ -151,13 +148,13 @@ + - @@ -195,17 +192,8 @@ - - - - - - - - - - - + + @@ -233,8 +221,8 @@ - - + + diff --git a/resources/StdMeshers.xml b/resources/StdMeshers.xml new file mode 100644 index 000000000..49aae9d0d --- /dev/null +++ b/resources/StdMeshers.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/mesh_edit_group.png b/resources/mesh_edit_group.png new file mode 100644 index 0000000000000000000000000000000000000000..4747a66b97d30a4f9be6a1a4d6807e645fc7ff03 GIT binary patch literal 543 zcmV+)0^t3LP)R=mT z>`ZZmrCejut#+~TEG)9c!Yvl}EOvJ?SwkKSyf-ud|7QO8o^n?vLS|bJPs?`zZo}*W z@bI*(3g27xWyB4)=R<~n?!jG|2m)k~Bj6+Cv9_J=ZX~+980yo97lOq#@u#sdYkDnOl*U7uzo^^Fwbdw3aecplQ~d<9_i zICwRmHhsWUJU~3h7tis<->ezmt`7M-t9F;ov*-95$DJMkY0_i+pb5|{>NWkX%B9O} z3*ioh=x$`la_}y~uW1TlelL_7Dqo+=EnW(&OS30C?|_o&S9Kc`v2?HsXf@Z&Y|fgp h#+kC9i^jS*djn1T4eyPjt^NQ2002ovPDHLkV1fx@@FV~L literal 0 HcmV?d00001 diff --git a/resources/mesh_free_edges.png b/resources/mesh_free_edges.png new file mode 100755 index 0000000000000000000000000000000000000000..5813e11e6544dc6e0178d9c93f540a616d837134 GIT binary patch literal 489 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VOS+@4BLl<6zM9{GlYxANWRD>fq}8a)5S5QVouVZ|Nrfo zO&J{+3}WL4Gx*1v=*7#zp&(YmnA4V(@h4sFnnMFak_(^ngv431czmK~ zuRC~jiqqDA6O({i6HNt3Jn{iIFcS4 zi)3)L-8eOscdJp5(Rl_Yj>8TDy?HOTd8$i_#GVc0iP*i5b#*r*Q-`2!qVjH`v=?7r z-{5`t;6cKJgog~54HyI*Bu=u)9^g5g#-Yxx&dkj1Y(L?zq#D0~0}HQ9x#S50N5+Gm zGBz^u4R78n9G(+1ciEvQj7%J>8yC!Q{${r6G>a>XBufR$yy~A-r3sh0fyS{lEs_(n zJh73p7^pi%e-U#7gVKxC8RZA{SgM4lpH2Y!=EGF8s|D8`l^I0RT4aDuh=}Dl=e4lI ziRnq~mm5b|8JId&d=hvQy9LbVSl_td&6nrb<&)mD0L?m-sc_=xrGF^0{P4g Yt=b*-KOWv&4vZ@XPgg&ebxsLQ0EKg`2mk;8 literal 0 HcmV?d00001 diff --git a/resources/mesh_make_group.png b/resources/mesh_make_group.png new file mode 100644 index 0000000000000000000000000000000000000000..19ba2e66eaaf380a718f336b6145601380036e2e GIT binary patch literal 432 zcmV;h0Z;ykP)((cdl$S3t@!YVSZgvg3x<#>KVd+Xa#4z9|d96>j-?T%} z?c*ZXF_wUZs(a}nPYT$MO8fRM3GFv+grDdDH=*hpLe+ir$hPZNyShvwm3Y#&!Vn6`Pf5z&kV+f{WmAO_o1tQ?<6YicC0Ee0000>fq^mG)5S5QVouVZ|Nrfo zO&J{+3}c%i>G|(CBZ!%ise?6^VfMlU35hD#92yvsT=<+PBwk-{Y;Y&K zmRIjt?DE!yoby>37+bD72soIDND6FXP-rmVxpS+e*HJTsd;P*4It-FL0uB+pEQ~d6 zNyVwo&dz&#rkpWuU^rwT;Ide{s{Xqt+j^T~5$32{Q5$wiC^Q5lNxn&062Z2UFGb^w zL5Z`4g@uGggv9|99tIWxw@r@hvu3TRNpZHYw2+jDkoeX3=Da~=1A|hA!miT}ZJb;j zevckJ{K1e?&o24w$tx34HGZ(|tX4WQ7h}~llujrdQ2ub|^!3%uv*W;yu#}mYEd0!9 zLgI-y7j_0lmkXy2-Z#Z^d{NVzevrX|K``{z0VM{Jw3aJOECPPa7x#9{&E5eNPc#*< z{oK5_TMW#5_|-_m`tQ%L?Gq$5fFV#I#ZjcHk-uq!;M9zopr0Q|C}Q~&?~ literal 0 HcmV?d00001 diff --git a/resources/mesh_points.png b/resources/mesh_points.png new file mode 100644 index 0000000000000000000000000000000000000000..f0d2c78a8647dc75ce74b92d72c89e174c949f61 GIT binary patch literal 499 zcmVRB+wodZ#fnEAd5bUz4$;|C|>neU!eFzZEw>2!MZ&pG3&;r zLLCTMmfde=elxRzeU zsUUKCVfnJ`jj#pQUeh$~Mo~rYfKjY*FHnMut#yIE978iTS$~ASxeh#(BST>Oww3T| z7wEjdaH8W;j(W$;%%Sd#QIL#(?6@-qK73!xmnHM3d2==fzTiZP8|kz_px0ut7M@>s6fXvaH;fu8BUri6!c!T(!^f5RT6#Wozv_&oJ3cqCC&DSYygv=}W;m;BBB+ zRg~w}Nl_NxstSN6I*@}nRmDsV=TdG9(oPZ9TGu!!%0d7%(nwYJ{zP>n3|mIvb@K`! zauD);P7Nc3!SAn4H5tNawO*0u6(oQW!Ycpg20f_sU2-RyXfLQg!eBCp`lI?ASX)zs p`{e#27@Th#pn4DMrCb7P><1vgh>SvKf2{xj002ovPDHLkV1iRA*X;lR literal 0 HcmV?d00001 diff --git a/resources/mesh_tree_group.png b/resources/mesh_tree_group.png new file mode 100644 index 0000000000000000000000000000000000000000..cfcfc687f397eebeaea38b740f9eef8ba18c79f0 GIT binary patch literal 411 zcmV;M0c8G(P)h*kgq0VqjC zK~#90g_Au_!$1&)zlkCg(WPWlrCYg8atca%sNHY?8oC@HC2~cdGRJUhWf+F|N70b=!HX%C&%=IjH~u002ovPDHLk FV1j0Ws9OL4 literal 0 HcmV?d00001 diff --git a/resources/mesh_tree_importedmesh.png b/resources/mesh_tree_importedmesh.png new file mode 100644 index 0000000000000000000000000000000000000000..0c37d0a7ec42c925da869172f040469d614828e7 GIT binary patch literal 912 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh3?wzC-F?i!z|0Wf6XFWwGW=)Q+H&nbkRAo2 zAuz&1Ann3uKVTMMDhcun{?G7qyMY&wXY1+W7*cU7^&B@Bg8~Qhg_+;?7q5HTE+i + +#include +#include +#include +#include +#include +#include + +#include "SMDS_Mesh.hxx" +#include "SMDS_Iterator.hxx" +#include "SMDS_MeshElement.hxx" +#include "SMDS_MeshNode.hxx" + +#include "SMESH_Controls.hxx" + +/* + AUXILIARY METHODS +*/ + +static inline double getAngle( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 ) +{ + return gp_Vec( P1 - P2 ).Angle( gp_Vec( P3 - P2 ) ); +} + +static inline double getArea( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 ) +{ + gp_Vec aVec1( P2 - P1 ); + gp_Vec aVec2( P3 - P1 ); + return ( aVec1 ^ aVec2 ).Magnitude() * 0.5; +} + +static inline double getArea( const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3 ) +{ + return getArea( P1.XYZ(), P2.XYZ(), P3.XYZ() ); +} + +static inline double getDistance( const gp_XYZ& P1, const gp_XYZ& P2 ) +{ + double aDist = gp_Pnt( P1 ).Distance( gp_Pnt( P2 ) ); + return aDist; +} + +static int getNbMultiConnection( SMDS_Mesh* theMesh, const int theId ) +{ + if ( theMesh == 0 ) + return 0; + + const SMDS_MeshElement* anEdge = theMesh->FindElement( theId ); + if ( anEdge == 0 || anEdge->GetType() != SMDSAbs_Edge || anEdge->NbNodes() != 2 ) + return 0; + + TColStd_MapOfInteger aMap; + + int aResult = 0; + SMDS_ElemIteratorPtr anIter = anEdge->nodesIterator(); + if ( anIter != 0 ) + { + while( anIter->more() ) + { + const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next(); + if ( aNode == 0 ) + return 0; + SMDS_ElemIteratorPtr anElemIter = aNode->GetInverseElementIterator(); + while( anElemIter->more() ) + { + const SMDS_MeshElement* anElem = anElemIter->next(); + if ( anElem != 0 && anElem->GetType() != SMDSAbs_Edge ) + { + int anId = anElem->GetID(); + + if ( anIter->more() ) // i.e. first node + aMap.Add( anId ); + else if ( aMap.Contains( anId ) ) + aResult++; + } + } + } + } + + return aResult; +} + + +using namespace SMESH::Controls; + +/* + FUNCTORS +*/ + +/* + Class : NumericalFunctor + Description : Base class for numerical functors +*/ +NumericalFunctor::NumericalFunctor(): + myMesh(NULL) +{} + +void NumericalFunctor::SetMesh( SMDS_Mesh* theMesh ) +{ + myMesh = theMesh; +} + +bool NumericalFunctor::getPoints( const int theId, + TColgp_SequenceOfXYZ& theRes ) const +{ + theRes.Clear(); + + if ( myMesh == 0 ) + return false; + + // Get nodes of the face + const SMDS_MeshElement* anElem = myMesh->FindElement( theId ); + if ( anElem == 0 || anElem->GetType() != GetType() ) + return false; + + int nbNodes = anElem->NbNodes(); + + SMDS_ElemIteratorPtr anIter = anElem->nodesIterator(); + if ( anIter != 0 ) + { + while( anIter->more() ) + { + const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next(); + if ( aNode != 0 ) + theRes.Append( gp_XYZ( aNode->X(), aNode->Y(), aNode->Z() ) ); + } + } + + return true; +} + + +/* + Class : MinimumAngle + Description : Functor for calculation of minimum angle +*/ +double MinimumAngle::GetValue( long theId ) +{ + TColgp_SequenceOfXYZ P; + if ( !getPoints( theId, P ) || P.Length() != 3 && P.Length() != 4 ) + return 0; + + double aMin; + + if ( P.Length() == 3 ) + { + double A0 = getAngle( P( 3 ), P( 1 ), P( 2 ) ); + double A1 = getAngle( P( 1 ), P( 2 ), P( 3 ) ); + double A2 = getAngle( P( 2 ), P( 3 ), P( 1 ) ); + + aMin = Min( A0, Min( A1, A2 ) ); + } + else + { + double A0 = getAngle( P( 4 ), P( 1 ), P( 2 ) ); + double A1 = getAngle( P( 1 ), P( 2 ), P( 3 ) ); + double A2 = getAngle( P( 2 ), P( 3 ), P( 4 ) ); + double A3 = getAngle( P( 3 ), P( 4 ), P( 1 ) ); + + aMin = Min( Min( A0, A1 ), Min( A2, A3 ) ); + } + + return aMin * 180 / PI; +} + +SMDSAbs_ElementType MinimumAngle::GetType() const +{ + return SMDSAbs_Face; +} + + +/* + Class : AspectRatio + Description : Functor for calculating aspect ratio +*/ +double AspectRatio::GetValue( long theId ) +{ + TColgp_SequenceOfXYZ P; + if ( !getPoints( theId, P ) || P.Length() != 3 && P.Length() != 4 ) + return 0; + + int nbNodes = P.Length(); + + // Compute lengths of the sides + + double aLen[ nbNodes ]; + for ( int i = 0; i < nbNodes - 1; i++ ) + aLen[ i ] = getDistance( P( i + 1 ), P( i + 2 ) ); + aLen[ nbNodes - 1 ] = getDistance( P( 1 ), P( nbNodes ) ); + + // Compute aspect ratio + + if ( nbNodes == 3 ) + { + double aMaxLen = Max( aLen[ 0 ], Max( aLen[ 1 ], aLen[ 2 ] ) ); + double anArea = getArea( P( 1 ), P( 2 ), P( 3 ) ); + static double aCoef = sqrt( 3. ) / 4; + + return anArea != 0 ? aCoef * aMaxLen * aMaxLen / anArea : 0; + } + else + { + double aMaxLen = Max( Max( aLen[ 0 ], aLen[ 1 ] ), Max( aLen[ 2 ], aLen[ 3 ] ) ); + double aMinLen = Min( Min( aLen[ 0 ], aLen[ 1 ] ), Min( aLen[ 2 ], aLen[ 3 ] ) ); + + return aMinLen != 0 ? aMaxLen / aMinLen : 0; + } +} + +SMDSAbs_ElementType AspectRatio::GetType() const +{ + return SMDSAbs_Face; +} + + +/* + Class : Warping + Description : Functor for calculating warping +*/ +double Warping::GetValue( long theId ) +{ + TColgp_SequenceOfXYZ P; + if ( !getPoints( theId, P ) || P.Length() != 4 ) + return 0; + + gp_XYZ G = ( P( 1 ) + P( 2 ) + P( 3 ) + P( 4 ) ) / 4; + + double A1 = ComputeA( P( 1 ), P( 2 ), P( 3 ), G ); + double A2 = ComputeA( P( 2 ), P( 3 ), P( 4 ), G ); + double A3 = ComputeA( P( 3 ), P( 4 ), P( 1 ), G ); + double A4 = ComputeA( P( 4 ), P( 1 ), P( 2 ), G ); + + return Max( Max( A1, A2 ), Max( A3, A4 ) ); +} + +double Warping::ComputeA( const gp_XYZ& thePnt1, + const gp_XYZ& thePnt2, + const gp_XYZ& thePnt3, + const gp_XYZ& theG ) const +{ + double aLen1 = gp_Pnt( thePnt1 ).Distance( gp_Pnt( thePnt2 ) ); + double aLen2 = gp_Pnt( thePnt2 ).Distance( gp_Pnt( thePnt3 ) ); + double L = Min( aLen1, aLen2 ) * 0.5; + + gp_XYZ GI = ( thePnt2 - thePnt1 ) / 2. - theG; + gp_XYZ GJ = ( thePnt3 - thePnt2 ) / 2. - theG; + gp_XYZ N = GI.Crossed( GJ ); + N.Normalize(); + + double H = gp_Vec( thePnt2 - theG ).Dot( gp_Vec( N ) ); + return asin( fabs( H / L ) ) * 180 / PI; +} + +SMDSAbs_ElementType Warping::GetType() const +{ + return SMDSAbs_Face; +} + + +/* + Class : Taper + Description : Functor for calculating taper +*/ +double Taper::GetValue( long theId ) +{ + TColgp_SequenceOfXYZ P; + if ( !getPoints( theId, P ) || P.Length() != 4 ) + return 0; + + // Compute taper + double J1 = getArea( P( 4 ), P( 1 ), P( 2 ) ) / 2; + double J2 = getArea( P( 3 ), P( 1 ), P( 2 ) ) / 2; + double J3 = getArea( P( 2 ), P( 3 ), P( 4 ) ) / 2; + double J4 = getArea( P( 3 ), P( 4 ), P( 1 ) ) / 2; + + double JA = 0.25 * ( J1 + J2 + J3 + J4 ); + + double T1 = fabs( ( J1 - JA ) / JA ); + double T2 = fabs( ( J2 - JA ) / JA ); + double T3 = fabs( ( J3 - JA ) / JA ); + double T4 = fabs( ( J4 - JA ) / JA ); + + return Max( Max( T1, T2 ), Max( T3, T4 ) ); +} + +SMDSAbs_ElementType Taper::GetType() const +{ + return SMDSAbs_Face; +} + + +/* + Class : Skew + Description : Functor for calculating skew in degrees +*/ +static inline double skewAngle( const gp_XYZ& p1, const gp_XYZ& p2, const gp_XYZ& p3 ) +{ + gp_XYZ p12 = ( p2 + p1 ) / 2; + gp_XYZ p23 = ( p3 + p2 ) / 2; + gp_XYZ p31 = ( p3 + p1 ) / 2; + + return gp_Vec( p31 - p2 ).Angle( p12 - p23 ); +} + +double Skew::GetValue( long theId ) +{ + TColgp_SequenceOfXYZ P; + if ( !getPoints( theId, P ) || P.Length() != 3 && P.Length() != 4 ) + return 0; + + // Compute skew + static double PI2 = PI / 2; + if ( P.Length() == 3 ) + { + double A0 = fabs( PI2 - skewAngle( P( 3 ), P( 1 ), P( 2 ) ) ); + double A1 = fabs( PI2 - skewAngle( P( 1 ), P( 2 ), P( 3 ) ) ); + double A2 = fabs( PI2 - skewAngle( P( 2 ), P( 3 ), P( 1 ) ) ); + + return Max( A0, Max( A1, A2 ) ) * 180 / PI; + } + else + { + gp_XYZ p12 = ( P( 1 ) + P( 2 ) ) / 2; + gp_XYZ p23 = ( P( 2 ) + P( 3 ) ) / 2; + gp_XYZ p34 = ( P( 3 ) + P( 4 ) ) / 2; + gp_XYZ p41 = ( P( 4 ) + P( 1 ) ) / 2; + + double A = fabs( PI2 - gp_Vec( p34 - p12 ).Angle( p23 - p41 ) ); + + return A * 180 / PI; + } +} + +SMDSAbs_ElementType Skew::GetType() const +{ + return SMDSAbs_Face; +} + + +/* + Class : Area + Description : Functor for calculating area +*/ +double Area::GetValue( long theId ) +{ + TColgp_SequenceOfXYZ P; + if ( !getPoints( theId, P ) || P.Length() != 3 && P.Length() != 4 ) + return 0; + + if ( P.Length() == 3 ) + return getArea( P( 1 ), P( 2 ), P( 3 ) ); + else + return getArea( P( 1 ), P( 2 ), P( 3 ) ) + getArea( P( 1 ), P( 3 ), P( 4 ) ); +} + +SMDSAbs_ElementType Area::GetType() const +{ + return SMDSAbs_Face; +} + + +/* + Class : Length + Description : Functor for calculating length off edge +*/ +double Length::GetValue( long theId ) +{ + TColgp_SequenceOfXYZ P; + return getPoints( theId, P ) && P.Length() == 2 ? getDistance( P( 1 ), P( 2 ) ) : 0; +} + +SMDSAbs_ElementType Length::GetType() const +{ + return SMDSAbs_Edge; +} + + +/* + Class : MultiConnection + Description : Functor for calculating number of faces conneted to the edge +*/ +double MultiConnection::GetValue( long theId ) +{ + return getNbMultiConnection( myMesh, theId ); +} + +SMDSAbs_ElementType MultiConnection::GetType() const +{ + return SMDSAbs_Edge; +} + + +/* + PREDICATES +*/ + +/* + Class : FreeBorders + Description : Predicate for free borders +*/ + +FreeBorders::FreeBorders() +{ + myMesh = 0; +} + +void FreeBorders::SetMesh( SMDS_Mesh* theMesh ) +{ + myMesh = theMesh; +} + +bool FreeBorders::IsSatisfy( long theId ) +{ + return getNbMultiConnection( myMesh, theId ) == 1; +} + +SMDSAbs_ElementType FreeBorders::GetType() const +{ + return SMDSAbs_Edge; +} + + +/* + Class : FreeEdges + Description : Predicate for free Edges +*/ +FreeEdges::FreeEdges() +{ + myMesh = 0; +} + +void FreeEdges::SetMesh( SMDS_Mesh* theMesh ) +{ + myMesh = theMesh; +} + +bool FreeEdges::IsSatisfy( long theId ) +{ + return getNbMultiConnection( myMesh, theId ) == 1; +} + +SMDSAbs_ElementType FreeEdges::GetType() const +{ + return SMDSAbs_Face; +} + +FreeEdges::Border::Border(long thePntId1, long thePntId2){ + PntId[0] = thePntId1; PntId[1] = thePntId2; + if(thePntId1 > thePntId2){ + PntId[1] = thePntId1; PntId[0] = thePntId2; + } +} + +//bool operator<(const FreeEdges::Border& x, const FreeEdges::Border& y){ +// if(x.PntId[0] < y.PntId[0]) return true; +// if(x.PntId[0] == y.PntId[0]) +// if(x.PntId[1] < y.PntId[1]) return true; +// return false; +//} + +namespace SMESH{ + namespace Controls{ + struct EdgeBorder: public FreeEdges::Border{ + long ElemId; + EdgeBorder(long theElemId, long thePntId1, long thePntId2): + FreeEdges::Border(thePntId1,thePntId2), + ElemId(theElemId) + {} + }; + + bool operator<(const FreeEdges::Border& x, const FreeEdges::Border& y){ + if(x.PntId[0] < y.PntId[0]) return true; + if(x.PntId[0] == y.PntId[0]) + if(x.PntId[1] < y.PntId[1]) return true; + return false; + } + + typedef std::set EdgeBorderS; + + inline void UpdateBorders(const EdgeBorder& theBorder, + EdgeBorderS& theRegistry, + EdgeBorderS& theContainer) + { + if(theRegistry.find(theBorder) == theRegistry.end()){ + theRegistry.insert(theBorder); + theContainer.insert(theBorder); + }else{ + theContainer.erase(theBorder); + } + } + + } +} + +void FreeEdges::GetBoreders(Borders& theBorders) +{ + EdgeBorderS aRegistry; + EdgeBorderS aContainer; + SMDS_FaceIteratorPtr anIter = myMesh->facesIterator(); + for(; anIter->more(); ){ + const SMDS_MeshFace* anElem = anIter->next(); + long anElemId = anElem->GetID(); + SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator(); + long aNodeId[2]; + const SMDS_MeshElement* aNode; + if(aNodesIter->more()){ + aNode = aNodesIter->next(); + aNodeId[0] = aNodeId[1] = aNode->GetID(); + } + for(; aNodesIter->more(); ){ + aNode = aNodesIter->next(); + EdgeBorder aBorder(anElemId,aNodeId[1],aNode->GetID()); + aNodeId[1] = aNode->GetID(); + //std::cout<SetMesh( theMesh ); +} + +void Comparator::SetMargin( double theValue ) +{ + myMargin = theValue; +} + +void Comparator::SetNumFunctor( NumericalFunctorPtr theFunct ) +{ + myFunctor = theFunct; +} + +SMDSAbs_ElementType Comparator::GetType() const +{ + return myFunctor ? myFunctor->GetType() : SMDSAbs_All; +} + + +/* + Class : LessThan + Description : Comparator "<" +*/ +bool LessThan::IsSatisfy( long theId ) +{ + return myFunctor && myFunctor->GetValue( theId ) < myMargin; +} + + +/* + Class : MoreThan + Description : Comparator ">" +*/ +bool MoreThan::IsSatisfy( long theId ) +{ + return myFunctor && myFunctor->GetValue( theId ) > myMargin; +} + + +/* + Class : EqualTo + Description : Comparator "=" +*/ +EqualTo::EqualTo(): + myToler(Precision::Confusion()) +{} + +bool EqualTo::IsSatisfy( long theId ) +{ + return myFunctor && fabs( myFunctor->GetValue( theId ) - myMargin ) < myToler; +} + +void EqualTo::SetTolerance( double theToler ) +{ + myToler = theToler; +} + + +/* + Class : LogicalNOT + Description : Logical NOT predicate +*/ +LogicalNOT::LogicalNOT() +{} + +LogicalNOT::~LogicalNOT() +{} + +bool LogicalNOT::IsSatisfy( long theId ) +{ + return myPredicate && !myPredicate->IsSatisfy( theId ); +} + +void LogicalNOT::SetMesh( SMDS_Mesh* theMesh ) +{ + if ( myPredicate ) + myPredicate->SetMesh( theMesh ); +} + +void LogicalNOT::SetPredicate( PredicatePtr thePred ) +{ + myPredicate = thePred; +} + +SMDSAbs_ElementType LogicalNOT::GetType() const +{ + return myPredicate ? myPredicate->GetType() : SMDSAbs_All; +} + + +/* + Class : LogicalBinary + Description : Base class for binary logical predicate +*/ +LogicalBinary::LogicalBinary() +{} + +LogicalBinary::~LogicalBinary() +{} + +void LogicalBinary::SetMesh( SMDS_Mesh* theMesh ) +{ + if ( myPredicate1 ) + myPredicate1->SetMesh( theMesh ); + + if ( myPredicate2 ) + myPredicate2->SetMesh( theMesh ); +} + +void LogicalBinary::SetPredicate1( PredicatePtr thePredicate ) +{ + myPredicate1 = thePredicate; +} + +void LogicalBinary::SetPredicate2( PredicatePtr thePredicate ) +{ + myPredicate2 = thePredicate; +} + +SMDSAbs_ElementType LogicalBinary::GetType() const +{ + if ( !myPredicate1 || !myPredicate2 ) + return SMDSAbs_All; + + SMDSAbs_ElementType aType1 = myPredicate1->GetType(); + SMDSAbs_ElementType aType2 = myPredicate2->GetType(); + + return aType1 == aType2 ? aType1 : SMDSAbs_All; +} + + +/* + Class : LogicalAND + Description : Logical AND +*/ +bool LogicalAND::IsSatisfy( long theId ) +{ + return + myPredicate1 && + myPredicate2 && + myPredicate1->IsSatisfy( theId ) && + myPredicate2->IsSatisfy( theId ); +} + + +/* + Class : LogicalOR + Description : Logical OR +*/ +bool LogicalOR::IsSatisfy( long theId ) +{ + return + myPredicate1 && + myPredicate2 && + myPredicate1->IsSatisfy( theId ) || + myPredicate2->IsSatisfy( theId ); +} + + +/* + FILTER +*/ + +Filter::Filter() +{} + +Filter::~Filter() +{} + +void Filter::SetPredicate( PredicatePtr thePredicate ) +{ + myPredicate = thePredicate; +} + +Filter::TIdSequence +Filter::GetElementsId( SMDS_Mesh* theMesh ) +{ + TIdSequence aSequence; + if ( !theMesh || !myPredicate ) return aSequence; + + myPredicate->SetMesh( theMesh ); + + SMDSAbs_ElementType aType = myPredicate->GetType(); + switch(aType){ + case SMDSAbs_Edge:{ + SMDS_EdgeIteratorPtr anIter = theMesh->edgesIterator(); + if ( anIter != 0 ) { + while( anIter->more() ) { + const SMDS_MeshElement* anElem = anIter->next(); + long anId = anElem->GetID(); + if ( myPredicate->IsSatisfy( anId ) ) + aSequence.push_back( anId ); + } + } + } + case SMDSAbs_Face:{ + SMDS_FaceIteratorPtr anIter = theMesh->facesIterator(); + if ( anIter != 0 ) { + while( anIter->more() ) { + const SMDS_MeshElement* anElem = anIter->next(); + long anId = anElem->GetID(); + if ( myPredicate->IsSatisfy( anId ) ) + aSequence.push_back( anId ); + } + } + } + } + return aSequence; +} diff --git a/src/Controls/SMESH_Controls.hxx b/src/Controls/SMESH_Controls.hxx new file mode 100644 index 000000000..1c771eb12 --- /dev/null +++ b/src/Controls/SMESH_Controls.hxx @@ -0,0 +1,340 @@ +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + +#ifndef _SMESH_CONTROLS_HXX_ +#define _SMESH_CONTROLS_HXX_ + +#include +#include +#include +#include "SMDSAbs_ElementType.hxx" + +class SMDS_Mesh; +class gp_Pnt; +class gp_XYZ; +class TColgp_SequenceOfXYZ; + +namespace SMESH{ + namespace Controls{ + class Functor{ + public: + ~Functor(){} + virtual void SetMesh( SMDS_Mesh* theMesh ) = 0; + }; + typedef boost::shared_ptr FunctorPtr; + + class NumericalFunctor: public virtual Functor{ + public: + NumericalFunctor(); + virtual void SetMesh( SMDS_Mesh* theMesh ); + virtual double GetValue( long theElementId ) = 0; + virtual SMDSAbs_ElementType GetType() const = 0; + + protected: + bool getPoints( const int theId, + TColgp_SequenceOfXYZ& theRes ) const; + protected: + SMDS_Mesh* myMesh; + }; + typedef boost::shared_ptr NumericalFunctorPtr; + + + /* + Class : SMESH_MinimumAngle + Description : Functor for calculation of minimum angle + */ + class MinimumAngle: public virtual NumericalFunctor{ + public: + virtual double GetValue( long theElementId ); + virtual SMDSAbs_ElementType GetType() const; + }; + + + /* + Class : AspectRatio + Description : Functor for calculating aspect ratio + */ + class AspectRatio: public virtual NumericalFunctor{ + public: + virtual double GetValue( long theElementId ); + virtual SMDSAbs_ElementType GetType() const; + }; + + + /* + Class : Warping + Description : Functor for calculating warping + */ + class Warping: public virtual NumericalFunctor{ + public: + virtual double GetValue( long theElementId ); + virtual SMDSAbs_ElementType GetType() const; + + private: + double ComputeA( const gp_XYZ&, const gp_XYZ&, + const gp_XYZ&, const gp_XYZ& ) const; + }; + + + /* + Class : Taper + Description : Functor for calculating taper + */ + class Taper: public virtual NumericalFunctor{ + public: + virtual double GetValue( long theElementId ); + virtual SMDSAbs_ElementType GetType() const; + }; + + + /* + Class : Skew + Description : Functor for calculating skew in degrees + */ + class Skew: public virtual NumericalFunctor{ + public: + virtual double GetValue( long theElementId ); + virtual SMDSAbs_ElementType GetType() const; + }; + + + /* + Class : Area + Description : Functor for calculating area + */ + class Area: public virtual NumericalFunctor{ + public: + virtual double GetValue( long theElementId ); + virtual SMDSAbs_ElementType GetType() const; + }; + + + /* + Class : Length + Description : Functor for calculating length of edge + */ + class Length: public virtual NumericalFunctor{ + public: + virtual double GetValue( long theElementId ); + virtual SMDSAbs_ElementType GetType() const; + }; + + + /* + Class : MultiConnection + Description : Functor for calculating number of faces conneted to the edge + */ + class MultiConnection: public virtual NumericalFunctor{ + public: + virtual double GetValue( long theElementId ); + virtual SMDSAbs_ElementType GetType() const; + }; + + + /* + PREDICATES + */ + /* + Class : Predicate + Description : Base class for all predicates + */ + class Predicate: public virtual Functor{ + public: + virtual bool IsSatisfy( long theElementId ) = 0; + virtual SMDSAbs_ElementType GetType() const = 0; + }; + typedef boost::shared_ptr PredicatePtr; + + + + /* + Class : FreeBorders + Description : Predicate for free borders + */ + class FreeBorders: public virtual Predicate{ + public: + FreeBorders(); + virtual void SetMesh( SMDS_Mesh* theMesh ); + virtual bool IsSatisfy( long theElementId ); + virtual SMDSAbs_ElementType GetType() const; + + protected: + SMDS_Mesh* myMesh; + }; + + + /* + Class : FreeEdges + Description : Predicate for free Edges + */ + class FreeEdges: public virtual Predicate{ + public: + FreeEdges(); + virtual void SetMesh( SMDS_Mesh* theMesh ); + virtual bool IsSatisfy( long theElementId ); + virtual SMDSAbs_ElementType GetType() const; + struct Border{ + long PntId[2]; + Border(long thePntId1, long thePntId2); + }; + typedef long TElemId; + typedef std::map Borders; + void GetBoreders(Borders& theBorders); + + protected: + SMDS_Mesh* myMesh; + }; + typedef boost::shared_ptr FreeEdgesPtr; + + + /* + Class : Comparator + Description : Base class for comparators + */ + class Comparator: public virtual Predicate{ + public: + Comparator(); + virtual ~Comparator(); + virtual void SetMesh( SMDS_Mesh* theMesh ); + virtual void SetMargin(double theValue); + virtual void SetNumFunctor(NumericalFunctorPtr theFunct); + virtual bool IsSatisfy( long theElementId ) = 0; + virtual SMDSAbs_ElementType GetType() const; + + protected: + double myMargin; + NumericalFunctorPtr myFunctor; + }; + typedef boost::shared_ptr ComparatorPtr; + + + /* + Class : LessThan + Description : Comparator "<" + */ + class LessThan: public virtual Comparator{ + public: + virtual bool IsSatisfy( long theElementId ); + }; + + + /* + Class : MoreThan + Description : Comparator ">" + */ + class MoreThan: public virtual Comparator{ + public: + virtual bool IsSatisfy( long theElementId ); + }; + + + /* + Class : EqualTo + Description : Comparator "=" + */ + class EqualTo: public virtual Comparator{ + public: + EqualTo(); + virtual bool IsSatisfy( long theElementId ); + virtual void SetTolerance( double theTol ); + + private: + double myToler; + }; + typedef boost::shared_ptr EqualToPtr; + + + /* + Class : LogicalNOT + Description : Logical NOT predicate + */ + class LogicalNOT: public virtual Predicate{ + public: + LogicalNOT(); + virtual ~LogicalNOT(); + virtual bool IsSatisfy( long theElementId ); + virtual void SetMesh( SMDS_Mesh* theMesh ); + virtual void SetPredicate(PredicatePtr thePred); + virtual SMDSAbs_ElementType GetType() const; + + private: + PredicatePtr myPredicate; + }; + typedef boost::shared_ptr LogicalNOTPtr; + + + /* + Class : LogicalBinary + Description : Base class for binary logical predicate + */ + class LogicalBinary: public virtual Predicate{ + public: + LogicalBinary(); + virtual ~LogicalBinary(); + virtual void SetMesh( SMDS_Mesh* theMesh ); + virtual void SetPredicate1(PredicatePtr thePred); + virtual void SetPredicate2(PredicatePtr thePred); + virtual SMDSAbs_ElementType GetType() const; + + protected: + PredicatePtr myPredicate1; + PredicatePtr myPredicate2; + }; + typedef boost::shared_ptr LogicalBinaryPtr; + + + /* + Class : LogicalAND + Description : Logical AND + */ + class LogicalAND: public virtual LogicalBinary{ + public: + virtual bool IsSatisfy( long theElementId ); + }; + + + /* + Class : LogicalOR + Description : Logical OR + */ + class LogicalOR: public virtual LogicalBinary{ + public: + virtual bool IsSatisfy( long theElementId ); + }; + + + /* + FILTER + */ + class Filter{ + public: + Filter(); + virtual ~Filter(); + virtual void SetPredicate(PredicatePtr thePred); + typedef std::vector TIdSequence; + virtual TIdSequence GetElementsId( SMDS_Mesh* theMesh ); + + protected: + PredicatePtr myPredicate; + }; + }; +}; + + +#endif diff --git a/src/Driver/Document_Reader.cxx b/src/Driver/Document_Reader.cxx index edb1c77a9..26dcf1450 100644 --- a/src/Driver/Document_Reader.cxx +++ b/src/Driver/Document_Reader.cxx @@ -38,16 +38,3 @@ void Document_Reader::SetDocument(SMESHDS_Document * aDoc) { myDocument = aDoc; } - -void Document_Reader::Read() -{ - int myMeshId = myDocument->NewMesh(); - SMDS_Mesh * myMesh = myDocument->GetMesh(myMeshId); - myReader->SetMesh(myMesh); - myReader->SetFile(myFile); - myReader->Read(); -} - -Document_Reader::Document_Reader(Mesh_Reader* reader): myReader(reader) -{ -} diff --git a/src/Driver/Document_Reader.h b/src/Driver/Document_Reader.h index 719665856..2766466c2 100644 --- a/src/Driver/Document_Reader.h +++ b/src/Driver/Document_Reader.h @@ -28,22 +28,17 @@ #define _INCLUDE_DOCUMENT_READER #include "SMESHDS_Document.hxx" -#include "Mesh_Reader.h" #include class Document_Reader { public: - virtual void Read(); + virtual void Read() = 0; void SetFile(string); void SetDocument(SMESHDS_Document *); - Document_Reader(Mesh_Reader*); protected: - SMESHDS_Document * myDocument; + SMESHDS_Document * myDocument; string myFile; - - private: - Mesh_Reader* myReader; }; #endif diff --git a/src/Driver/Document_Writer.cxx b/src/Driver/Document_Writer.cxx index 95f195dc3..8704c1284 100644 --- a/src/Driver/Document_Writer.cxx +++ b/src/Driver/Document_Writer.cxx @@ -18,9 +18,14 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : Document_Writer.cxx +// Module : SMESH +using namespace std; #include "Document_Writer.h" -#include "utilities.h" void Document_Writer::SetFile(string aFile) { @@ -31,28 +36,3 @@ void Document_Writer::SetDocument(SMESHDS_Document * aDoc) { myDocument = aDoc; } - -void Document_Writer::Write() -{ - SCRUTE(myFile); - SMESHDS_Mesh * myMesh; - int nb_of_meshes = myDocument->NbMeshes(); //voir avec Yves - SCRUTE(nb_of_meshes); - - int numero = 0; - - myDocument->InitMeshesIterator(); - while(myDocument->MoreMesh()) - { - numero++; - myMesh = myDocument->NextMesh(); - myWriter->SetMesh(myMesh); - myWriter->SetFile(myFile); - myWriter->SetMeshId(numero); - myWriter->Add(); - } -} - -Document_Writer::Document_Writer(Mesh_Writer* writer): myWriter(writer) -{ -} diff --git a/src/Driver/Document_Writer.h b/src/Driver/Document_Writer.h index f50b59486..4aea9605c 100644 --- a/src/Driver/Document_Writer.h +++ b/src/Driver/Document_Writer.h @@ -28,21 +28,17 @@ #define _INCLUDE_DOCUMENT_WRITER #include "SMESHDS_Document.hxx" -#include "Mesh_Writer.h" #include class Document_Writer { - public:virtual void Write(); + public:virtual void Write() = 0; void SetFile(string); void SetDocument(SMESHDS_Document *); - Document_Writer(Mesh_Writer* ); - protected: - SMESHDS_Document * myDocument; + protected: SMESHDS_Document * myDocument; string myFile; - Mesh_Writer * myWriter; }; #endif diff --git a/src/Driver/Driver_Document.cxx b/src/Driver/Driver_Document.cxx new file mode 100644 index 000000000..159c1a85a --- /dev/null +++ b/src/Driver/Driver_Document.cxx @@ -0,0 +1,36 @@ +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + +#include "Driver_Document.h" + +Driver_Document::Driver_Document(): + myDocument(NULL) +{} + + +void Driver_Document::SetFile(const std::string& theFileName) +{ + myFile = theFileName; +} + + +void Driver_Document::SetDocument(SMESHDS_Document * theDocument) +{ + myDocument = theDocument; +} diff --git a/src/Driver/Driver_Document.h b/src/Driver/Driver_Document.h new file mode 100644 index 000000000..8d4ff5a68 --- /dev/null +++ b/src/Driver/Driver_Document.h @@ -0,0 +1,44 @@ +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + +#ifndef _INCLUDE_DRIVER_DOCUMENT +#define _INCLUDE_DRIVER_DOCUMENT + +#include + +class SMESHDS_Document; + +class Driver_Document +{ + public: + Driver_Document(); + virtual ~Driver_Document(){} + + virtual void Perform() = 0; + void SetFile(const std::string& theFileName); + void SetDocument(SMESHDS_Document *theDocument); + + protected: + SMESHDS_Document * myDocument; + std::string myFile; + +}; + + +#endif diff --git a/src/Driver/Driver_Mesh.cxx b/src/Driver/Driver_Mesh.cxx new file mode 100644 index 000000000..f656bdd5d --- /dev/null +++ b/src/Driver/Driver_Mesh.cxx @@ -0,0 +1,46 @@ +// SMESH Driver : implementaion of driver for reading and writing +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : Mesh_Reader.cxx +// Module : SMESH + +#include "Driver_Mesh.h" + +using namespace std; + +Driver_Mesh::Driver_Mesh(): + myFile(""), + myMeshId(-1) +{} + + +void Driver_Mesh::SetMeshId(int theMeshId) +{ + myMeshId = theMeshId; +} + + +void Driver_Mesh::SetFile(const std::string& theFileName) +{ + myFile = theFileName; +} diff --git a/src/Driver/Driver_Mesh.h b/src/Driver/Driver_Mesh.h new file mode 100644 index 000000000..0bfac0cd8 --- /dev/null +++ b/src/Driver/Driver_Mesh.h @@ -0,0 +1,57 @@ +// SMESH Driver : implementaion of driver for reading and writing +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : Mesh_Reader.h +// Module : SMESH + +#ifndef _INCLUDE_DRIVER_MESH +#define _INCLUDE_DRIVER_MESH + +#include + +class Driver_Mesh +{ + public: + Driver_Mesh(); + virtual ~Driver_Mesh(){} + + enum Status { + DRS_OK, + DRS_EMPTY, // a file contains no mesh with the given name + DRS_WARN_RENUMBER, // a file has overlapped ranges of element numbers, + // so the numbers from the file are ignored + DRS_WARN_SKIP_ELEM, // some elements were skipped due to incorrect file data + DRS_FAIL // general failure (exception etc.) + }; + + virtual Status Perform() = 0; + void SetMeshId(int theMeshId); + void SetFile(const std::string& theFileName); + + protected: + std::string myFile; + int myMeshId; + +}; + +#endif diff --git a/src/Driver/Driver_SMDS_Mesh.cxx b/src/Driver/Driver_SMDS_Mesh.cxx new file mode 100644 index 000000000..dae030df0 --- /dev/null +++ b/src/Driver/Driver_SMDS_Mesh.cxx @@ -0,0 +1,31 @@ +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + +#include "Driver_SMDS_Mesh.h" + +using namespace std; + +Driver_SMDS_Mesh::Driver_SMDS_Mesh(): + myMesh(NULL) +{} + +void Driver_SMDS_Mesh::SetMesh(SMDS_Mesh *theMesh) +{ + myMesh = theMesh; +} diff --git a/src/Driver/Driver_SMDS_Mesh.h b/src/Driver/Driver_SMDS_Mesh.h new file mode 100644 index 000000000..1ea37562d --- /dev/null +++ b/src/Driver/Driver_SMDS_Mesh.h @@ -0,0 +1,38 @@ +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + +#ifndef _INCLUDE_DRIVER_SMDS_MESH +#define _INCLUDE_DRIVER_SMDS_MESH + +#include "Driver_Mesh.h" + +class SMDS_Mesh; + +class Driver_SMDS_Mesh: public Driver_Mesh +{ + public: + Driver_SMDS_Mesh(); + void SetMesh(SMDS_Mesh *theMesh); + + protected: + SMDS_Mesh *myMesh; + +}; + +#endif diff --git a/src/Driver/Driver_SMESHDS_Mesh.cxx b/src/Driver/Driver_SMESHDS_Mesh.cxx new file mode 100644 index 000000000..2bf88277d --- /dev/null +++ b/src/Driver/Driver_SMESHDS_Mesh.cxx @@ -0,0 +1,31 @@ +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + +#include "Driver_SMESHDS_Mesh.h" + +using namespace std; + +Driver_SMESHDS_Mesh::Driver_SMESHDS_Mesh(): + myMesh(NULL) +{} + +void Driver_SMESHDS_Mesh::SetMesh(SMESHDS_Mesh *theMesh) +{ + myMesh = theMesh; +} diff --git a/src/Driver/Driver_SMESHDS_Mesh.h b/src/Driver/Driver_SMESHDS_Mesh.h new file mode 100644 index 000000000..b401dbd1c --- /dev/null +++ b/src/Driver/Driver_SMESHDS_Mesh.h @@ -0,0 +1,38 @@ +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + +#ifndef _INCLUDE_DRIVER_SMESHDS_MESH +#define _INCLUDE_DRIVER_SMESHDS_MESH + +#include "Driver_Mesh.h" + +class SMESHDS_Mesh; + +class Driver_SMESHDS_Mesh: public Driver_Mesh +{ + public: + Driver_SMESHDS_Mesh(); + void SetMesh(SMESHDS_Mesh *theMesh); + + protected: + SMESHDS_Mesh *myMesh; + +}; + +#endif diff --git a/src/Driver/Makefile.in b/src/Driver/Makefile.in index cad4d3b89..252d53062 100644 --- a/src/Driver/Makefile.in +++ b/src/Driver/Makefile.in @@ -35,28 +35,18 @@ VPATH=.:@srcdir@ @COMMENCE@ # header files -EXPORT_HEADERS = \ - SMESHDriver.h \ - Document_Reader.h \ - Document_Writer.h \ - Mesh_Reader.h \ - Mesh_Writer.h +EXPORT_HEADERS= Document_Reader.h Document_Writer.h Mesh_Reader.h Mesh_Writer.h # Libraries targets LIB = libMeshDriver.la -LIB_SRC = \ - SMESHDriver.cxx \ - Document_Reader.cxx \ - Document_Writer.cxx -# Mesh_Reader.cxx \ -# Mesh_Writer.cxx \ +LIB_SRC = Document_Reader.cxx Document_Writer.cxx Mesh_Reader.cxx Mesh_Writer.cxx LIB_CLIENT_IDL = LIB_SERVER_IDL = # additionnal information to compil and link file -CPPFLAGS += $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome +CPPFLAGS += $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS) CXXFLAGS += $(OCC_CXXFLAGS) $(MED2_INCLUDES) -rdynamic -ldl -I${KERNEL_ROOT_DIR}/include/salome LDFLAGS += $(MED2_LIBS) -lSMESHDS -lSMDS diff --git a/src/Driver/SMESHDriver.cxx b/src/Driver/SMESHDriver.cxx index e98932a80..83e9037a5 100644 --- a/src/Driver/SMESHDriver.cxx +++ b/src/Driver/SMESHDriver.cxx @@ -1,4 +1,4 @@ -// SMESH Driver : implementation of driver for reading and writing +// SMESH Driver : implementaion of driver for reading and writing // // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -18,97 +18,122 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESHDriver.cxx +// Module : SMESH +using namespace std; #include "SMESHDriver.h" #include #include -Document_Reader* SMESHDriver::GetDocumentReader(string Extension) -{ - // if there is not document reader in the driver create a default - // one with the mesh reader. - Document_Reader * docReader= - (Document_Reader*)getMeshDocumentDriver(Extension); - - if(docReader==NULL) - { - Mesh_Reader * reader=GetMeshReader(Extension); - if(reader==NULL) - { - MESSAGE("No driver known for this extension"); - return NULL; - } - return new Document_Reader(reader); - } - else return docReader; -} +//A enlever +#include "DriverMED_R_SMESHDS_Document.h" +#include "DriverMED_R_SMESHDS_Mesh.h" +#include "DriverMED_R_SMDS_Mesh.h" +#include "DriverMED_W_SMESHDS_Document.h" +#include "DriverMED_W_SMESHDS_Mesh.h" +#include "DriverMED_W_SMDS_Mesh.h" + +#include "DriverDAT_R_SMESHDS_Document.h" +#include "DriverDAT_R_SMESHDS_Mesh.h" +#include "DriverDAT_R_SMDS_Mesh.h" +#include "DriverDAT_W_SMESHDS_Document.h" +#include "DriverDAT_W_SMESHDS_Mesh.h" +#include "DriverDAT_W_SMDS_Mesh.h" +// + +Document_Reader* SMESHDriver::GetDocumentReader(string Extension, string Class) { + if (Extension==string("MED")) { + DriverMED_R_SMESHDS_Document* myDriver = new DriverMED_R_SMESHDS_Document(); + return (myDriver); + } + else if (Extension==string("DAT")) { + DriverDAT_R_SMESHDS_Document* myDriver = new DriverDAT_R_SMESHDS_Document(); + return (myDriver); + } + else { + MESSAGE("No driver known for this extension"); + return (Document_Reader*)NULL; + } -Document_Writer* SMESHDriver::GetDocumentWriter(string Extension) -{ - Mesh_Writer * writer=GetMeshWriter(Extension); - if(writer==NULL) - { - MESSAGE("No driver known for this extension"); - return NULL; - } - return new Document_Writer(writer); -} -Mesh_Reader* SMESHDriver::GetMeshReader(string extension) -{ - void * driver = getMeshDriver(extension, string("Reader")); - return (Mesh_Reader*)driver; } -Mesh_Writer* SMESHDriver::GetMeshWriter(string extension) -{ - void * driver = getMeshDriver(extension, string("Writer")); - return (Mesh_Writer*)driver; +Document_Writer* SMESHDriver::GetDocumentWriter(string Extension, string Class) { + if (Extension==string("MED")) { + DriverMED_W_SMESHDS_Document* myDriver = new DriverMED_W_SMESHDS_Document(); + return (myDriver); + } + else if (Extension==string("DAT")) { + DriverDAT_W_SMESHDS_Document* myDriver = new DriverDAT_W_SMESHDS_Document(); + return (myDriver); + } + else { + MESSAGE("No driver known for this extension"); + return (Document_Writer*)NULL; + } + + } -void * SMESHDriver::getMeshDriver(string extension, string type) -{ - string libName = string("libMeshDriver")+extension+string(".so"); - void * handle = dlopen(libName.c_str(), RTLD_LAZY); - if(!handle) - { - cerr << dlerror() << endl; - return NULL; - } - else - { - void * (*factory)(); - string symbol = string("SMESH_create")+extension+string("Mesh")+type; - factory = (void * (*)()) dlsym(handle, symbol.c_str()); - if(factory==NULL) - { - cerr << dlerror() << endl; - return NULL; - } - else return factory(); - } +Mesh_Reader* SMESHDriver::GetMeshReader(string Extension, string Class) { + if (Extension==string("MED")) { + + if (strcmp(Class.c_str(),"SMESHDS_Mesh")==0) { + DriverMED_R_SMESHDS_Mesh* myDriver = new DriverMED_R_SMESHDS_Mesh(); + return (myDriver); + } + else if (strcmp(Class.c_str(),"SMDS_Mesh")==0) { + DriverMED_R_SMDS_Mesh* myDriver = new DriverMED_R_SMDS_Mesh(); + return (myDriver); + } + + } + else if (Extension==string("DAT")) { + + if (strcmp(Class.c_str(),"SMESHDS_Mesh")==0) { + DriverDAT_R_SMESHDS_Mesh* myDriver = new DriverDAT_R_SMESHDS_Mesh(); + return (myDriver); + } + else if (strcmp(Class.c_str(),"SMDS_Mesh")==0) { + DriverDAT_R_SMDS_Mesh* myDriver = new DriverDAT_R_SMDS_Mesh(); + return (myDriver); + } + + } + + } -void * SMESHDriver::getMeshDocumentDriver(string extension) -{ - string libName = string("libMeshDriver")+extension+string(".so"); - void * handle = dlopen(libName.c_str(), RTLD_LAZY); - if(!handle) - { - cerr << dlerror() << endl; - return NULL; - } - else - { - void * (*factory)(); - string symbol = string("SMESH_create")+extension+string("DocumentReader"); - factory = (void * (*)()) dlsym(handle, symbol.c_str()); - if(factory==NULL) - { - cerr << dlerror() << endl; - return NULL; - } - else return factory(); - } +Mesh_Writer* SMESHDriver::GetMeshWriter(string Extension, string Class) { + if (Extension==string("MED")) { + + if (strcmp(Class.c_str(),"SMESHDS_Mesh")==0) { + DriverMED_W_SMESHDS_Mesh* myDriver = new DriverMED_W_SMESHDS_Mesh(); + return (myDriver); + } + else if (strcmp(Class.c_str(),"SMDS_Mesh")==0) { + DriverMED_W_SMDS_Mesh* myDriver = new DriverMED_W_SMDS_Mesh(); + return (myDriver); + } + + } + else if (Extension==string("DAT")) { + + if (strcmp(Class.c_str(),"SMESHDS_Mesh")==0) { + DriverDAT_W_SMESHDS_Mesh* myDriver = new DriverDAT_W_SMESHDS_Mesh(); + return (myDriver); + } + else if (strcmp(Class.c_str(),"SMDS_Mesh")==0) { + DriverDAT_W_SMDS_Mesh* myDriver = new DriverDAT_W_SMDS_Mesh(); + return (myDriver); + } + + } + } + diff --git a/src/Driver/SMESHDriver.h b/src/Driver/SMESHDriver.h index 119208c2e..78731c33d 100644 --- a/src/Driver/SMESHDriver.h +++ b/src/Driver/SMESHDriver.h @@ -32,17 +32,14 @@ #include "Mesh_Reader.h" #include "Mesh_Writer.h" -class SMESHDriver -{ +class SMESHDriver { + public : - static Document_Reader* GetDocumentReader(string Extension); - static Document_Writer* GetDocumentWriter(string Extension); + static Document_Reader* GetDocumentReader(string Extension, string Class); + static Document_Writer* GetDocumentWriter(string Extension, string Class); - static Mesh_Reader* GetMeshReader(string Extension); - static Mesh_Writer* GetMeshWriter(string Extension); + static Mesh_Reader* GetMeshReader(string Extension, string Class); + static Mesh_Writer* GetMeshWriter(string Extension, string Class); - private: - static void * getMeshDriver(string Extension, string type); - static void * getMeshDocumentDriver(string Extension); }; #endif diff --git a/src/DriverDAT/DAT_Test.cxx b/src/DriverDAT/DAT_Test.cxx new file mode 100644 index 000000000..a36b4dd10 --- /dev/null +++ b/src/DriverDAT/DAT_Test.cxx @@ -0,0 +1,28 @@ +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + +#include "DriverDAT_R_SMDS_Mesh.h" +#include "DriverDAT_W_SMDS_Mesh.h" + +int main(int argc, char** argv) +{ + DriverDAT_R_SMDS_Mesh aR; + DriverDAT_W_SMDS_Mesh aW; + return 1; +} diff --git a/src/DriverDAT/DriverDAT_R_SMDS_Mesh.cxx b/src/DriverDAT/DriverDAT_R_SMDS_Mesh.cxx index 0990acc5d..bd95f49fb 100644 --- a/src/DriverDAT/DriverDAT_R_SMDS_Mesh.cxx +++ b/src/DriverDAT/DriverDAT_R_SMDS_Mesh.cxx @@ -24,20 +24,10 @@ // File : DriverDAT_R_SMDS_Mesh.cxx // Module : SMESH +using namespace std; #include "DriverDAT_R_SMDS_Mesh.h" -#include "utilities.h" - -extern "C" -{ -/** - * Factory function which will be called by SMESHDriver - */ -void * SMESH_createDATMeshReader() -{ - return new DriverDAT_R_SMDS_Mesh(); -} -} +#include "utilities.h" DriverDAT_R_SMDS_Mesh::DriverDAT_R_SMDS_Mesh() { diff --git a/src/DriverDAT/DriverDAT_W_SMDS_Mesh.cxx b/src/DriverDAT/DriverDAT_W_SMDS_Mesh.cxx index d99a124fa..8f6a7068d 100644 --- a/src/DriverDAT/DriverDAT_W_SMDS_Mesh.cxx +++ b/src/DriverDAT/DriverDAT_W_SMDS_Mesh.cxx @@ -24,25 +24,17 @@ // File : DriverDAT_W_SMDS_Mesh.cxx // Module : SMESH +using namespace std; #include "DriverDAT_W_SMDS_Mesh.h" + #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" -#include "utilities.h" -extern "C" -{ - -/** - * Factory function which will be called by SMESHDriver - */ -void * SMESH_createDATMeshWriter() -{ - return new DriverDAT_W_SMDS_Mesh(); -} -} +#include "utilities.h" DriverDAT_W_SMDS_Mesh::DriverDAT_W_SMDS_Mesh() { + ; } DriverDAT_W_SMDS_Mesh::~DriverDAT_W_SMDS_Mesh() @@ -72,12 +64,12 @@ void DriverDAT_W_SMDS_Mesh::SetMeshId(int aMeshId) void DriverDAT_W_SMDS_Mesh::Add() { - MESSAGE("Adding a mesh to a DAT document. As DAT do not support more than one mesh in a file, the previous mesh is deleted"); - Write(); + ; } void DriverDAT_W_SMDS_Mesh::Write() { + int nbNodes, nbCells; int i; @@ -88,7 +80,7 @@ void DriverDAT_W_SMDS_Mesh::Write() fprintf(stderr, ">> ERREUR : ouverture du fichier %s \n", file2Read); exit(EXIT_FAILURE); } - + SCRUTE(myMesh); /**************************************************************************** * NOMBRES D'OBJETS * ****************************************************************************/ @@ -105,6 +97,9 @@ void DriverDAT_W_SMDS_Mesh::Write() nb_of_faces = myMesh->NbFaces(); nb_of_volumes = myMesh->NbVolumes(); nbCells = nb_of_edges + nb_of_faces + nb_of_volumes; + SCRUTE(nb_of_edges); + SCRUTE(nb_of_faces); + SCRUTE(nb_of_volumes); fprintf(stdout, "%d %d\n", nbNodes, nbCells); fprintf(myFileId, "%d %d\n", nbNodes, nbCells); @@ -116,15 +111,14 @@ void DriverDAT_W_SMDS_Mesh::Write() fprintf(stdout, "(* NOEUDS DU MAILLAGE : *)\n"); fprintf(stdout, "(************************)\n"); - SMDS_Iterator * itNodes=myMesh->nodesIterator(); + SMDS_NodeIteratorPtr itNodes=myMesh->nodesIterator(); while(itNodes->more()) { const SMDS_MeshNode * node = itNodes->next(); fprintf(myFileId, "%d %e %e %e\n", node->GetID(), node->X(), node->Y(), node->Z()); } - delete itNodes; - + /**************************************************************************** * ECRITURE DES ELEMENTS * ****************************************************************************/ @@ -133,10 +127,10 @@ void DriverDAT_W_SMDS_Mesh::Write() fprintf(stdout, "(**************************)"); /* Ecriture des connectivites, noms, numeros des mailles */ - SMDS_Iterator * itEdges=myMesh->edgesIterator(); + SMDS_EdgeIteratorPtr itEdges=myMesh->edgesIterator(); while(itEdges->more()) { - const SMDS_MeshEdge * elem = itEdges->next(); + const SMDS_MeshElement * elem = itEdges->next(); switch (elem->NbNodes()) { @@ -152,15 +146,13 @@ void DriverDAT_W_SMDS_Mesh::Write() } } - SMDS_Iterator * itNodes=elem->nodesIterator(); - while(itNodes->more()) - fprintf(myFileId, "%d ", itNodes->next()->GetID()); - + SMDS_ElemIteratorPtr it=elem->nodesIterator(); + while(it->more()) fprintf(myFileId, "%d ", it->next()->GetID()); + fprintf(myFileId, "\n"); } - delete itEdges; - SMDS_Iterator * itFaces=myMesh->facesIterator(); + SMDS_FaceIteratorPtr itFaces=myMesh->facesIterator(); while(itFaces->more()) { const SMDS_MeshElement * elem = itFaces->next(); @@ -184,16 +176,13 @@ void DriverDAT_W_SMDS_Mesh::Write() } } - SMDS_Iterator * itNodes=elem->nodesIterator(); - while(itNodes->more()) - fprintf(myFileId, "%d ", itNodes->next()->GetID()); - delete itNodes; - + SMDS_ElemIteratorPtr it=elem->nodesIterator(); + while(it->more()) fprintf(myFileId, "%d ", it->next()->GetID()); + fprintf(myFileId, "\n"); } - delete itFaces; - SMDS_Iterator * itVolumes=myMesh->volumesIterator(); + SMDS_VolumeIteratorPtr itVolumes=myMesh->volumesIterator(); while(itVolumes->more()) { const SMDS_MeshElement * elem = itVolumes->next(); @@ -207,14 +196,11 @@ void DriverDAT_W_SMDS_Mesh::Write() } } - SMDS_Iterator * itNodes=elem->nodesIterator(); - while(itNodes->more()) - fprintf(myFileId, "%d ", itNodes->next()->GetID()); - delete itNodes; + SMDS_ElemIteratorPtr it=elem->nodesIterator(); + while(it->more()) fprintf(myFileId, "%d ", it->next()->GetID()); fprintf(myFileId, "\n"); } - delete itVolumes; fclose(myFileId); } diff --git a/src/DriverDAT/DriverDAT_W_SMESHDS_Mesh.cxx b/src/DriverDAT/DriverDAT_W_SMESHDS_Mesh.cxx index 0c988c3d8..9518e2f78 100644 --- a/src/DriverDAT/DriverDAT_W_SMESHDS_Mesh.cxx +++ b/src/DriverDAT/DriverDAT_W_SMESHDS_Mesh.cxx @@ -125,14 +125,13 @@ void DriverDAT_W_SMESHDS_Mesh::Add() fprintf(stdout, "(* NOEUDS DU MAILLAGE : *)\n"); fprintf(stdout, "(************************)\n"); - SMDS_Iterator * itNodes=myMesh->nodesIterator(); + SMDS_NodeIteratorPtr itNodes=myMesh->nodesIterator(); while(itNodes->more()) { const SMDS_MeshNode * node = itNodes->next(); fprintf(myFileId, "%d %e %e %e\n", node->GetID(), node->X(), node->Y(), node->Z()); } - delete itNodes; /**************************************************************************** * ECRITURE DES ELEMENTS * @@ -142,7 +141,7 @@ void DriverDAT_W_SMESHDS_Mesh::Add() fprintf(stdout, "(**************************)"); /* Ecriture des connectivites, noms, numeros des mailles */ - SMDS_Iterator * itEdges=myMesh->edgesIterator(); + SMDS_EdgeIteratorPtr itEdges=myMesh->edgesIterator(); while(itEdges->more()) { const SMDS_MeshEdge * elem = itEdges->next(); @@ -161,15 +160,14 @@ void DriverDAT_W_SMESHDS_Mesh::Add() } } - SMDS_Iterator * itNodes=elem->nodesIterator(); + SMDS_ElemIteratorPtr itNodes=elem->nodesIterator(); while(itNodes->more()) fprintf(myFileId, "%d ", itNodes->next()->GetID()); fprintf(myFileId, "\n"); } - delete itEdges; - SMDS_Iterator * itFaces=myMesh->facesIterator(); + SMDS_FaceIteratorPtr itFaces=myMesh->facesIterator(); while(itFaces->more()) { const SMDS_MeshElement * elem = itFaces->next(); @@ -193,16 +191,14 @@ void DriverDAT_W_SMESHDS_Mesh::Add() } } - SMDS_Iterator * itNodes=elem->nodesIterator(); + SMDS_ElemIteratorPtr itNodes=elem->nodesIterator(); while(itNodes->more()) fprintf(myFileId, "%d ", itNodes->next()->GetID()); - delete itNodes; fprintf(myFileId, "\n"); } - delete itFaces; - SMDS_Iterator * itVolumes=myMesh->volumesIterator(); + SMDS_VolumeIteratorPtr itVolumes=myMesh->volumesIterator(); while(itVolumes->more()) { const SMDS_MeshElement * elem = itVolumes->next(); @@ -216,14 +212,12 @@ void DriverDAT_W_SMESHDS_Mesh::Add() } } - SMDS_Iterator * itNodes=elem->nodesIterator(); + SMDS_ElemIteratorPtr itNodes=elem->nodesIterator(); while(itNodes->more()) fprintf(myFileId, "%d ", itNodes->next()->GetID()); - delete itNodes; fprintf(myFileId, "\n"); } - delete itVolumes; fclose(myFileId); } diff --git a/src/DriverDAT/Makefile.in b/src/DriverDAT/Makefile.in index 8043bf715..12dd8b7ca 100644 --- a/src/DriverDAT/Makefile.in +++ b/src/DriverDAT/Makefile.in @@ -35,30 +35,18 @@ VPATH=.:@srcdir@ @COMMENCE@ # header files -EXPORT_HEADERS = \ - DriverDAT_R_SMDS_Mesh.h \ - DriverDAT_R_SMESHDS_Mesh.h \ - DriverDAT_W_SMDS_Mesh.h \ - DriverDAT_W_SMESHDS_Mesh.h -# DriverDAT_W_SMESHDS_Document.h \ -# DriverDAT_R_SMESHDS_Document.h \ +EXPORT_HEADERS= DriverDAT_R_SMDS_Mesh.h DriverDAT_R_SMESHDS_Mesh.h DriverDAT_R_SMESHDS_Document.h DriverDAT_W_SMDS_Mesh.h DriverDAT_W_SMESHDS_Mesh.h DriverDAT_W_SMESHDS_Document.h # Libraries targets LIB = libMeshDriverDAT.la -LIB_SRC = \ - DriverDAT_R_SMDS_Mesh.cxx \ - DriverDAT_R_SMESHDS_Mesh.cxx \ - DriverDAT_W_SMDS_Mesh.cxx \ - DriverDAT_W_SMESHDS_Mesh.cxx - #DriverDAT_W_SMESHDS_Document.cxx \ - #DriverDAT_R_SMESHDS_Document.cxx \ +LIB_SRC = DriverDAT_R_SMDS_Mesh.cxx DriverDAT_R_SMESHDS_Mesh.cxx DriverDAT_R_SMESHDS_Document.cxx DriverDAT_W_SMDS_Mesh.cxx DriverDAT_W_SMESHDS_Mesh.cxx DriverDAT_W_SMESHDS_Document.cxx LIB_CLIENT_IDL = LIB_SERVER_IDL = # additionnal information to compil and link file -CPPFLAGS += $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome +CPPFLAGS += $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS) CXXFLAGS += $(OCC_CXXFLAGS) $(MED2_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome LDFLAGS += $(MED2_LIBS) -lMeshDriver diff --git a/src/DriverMED/DriverMED_Family.cxx b/src/DriverMED/DriverMED_Family.cxx new file mode 100644 index 000000000..ee1123ccd --- /dev/null +++ b/src/DriverMED/DriverMED_Family.cxx @@ -0,0 +1,367 @@ +// SMESH DriverMED : tool to split groups on families +// +// Copyright (C) 2003 CEA +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +// +// +// +// File : DriverMED_Family.cxx +// Author : Julia DOROVSKIKH +// Module : SMESH +// $Header$ + +#include "DriverMED_Family.h" +#include + +//============================================================================= +/*! + * Split each group from list on some parts (families) + * on the basis of the elements membership in other groups from this list. + * Resulting families have no common elements. + */ +//============================================================================= +list DriverMED_Family::MakeFamilies + (const map & theSubMeshes, + const list& theGroups, + const bool doGroupOfNodes, + const bool doGroupOfEdges, + const bool doGroupOfFaces, + const bool doGroupOfVolumes) +{ + list aFamilies; + + string anAllNodesGroupName = "Group_Of_All_Nodes"; + string anAllEdgesGroupName = "Group_Of_All_Edges"; + string anAllFacesGroupName = "Group_Of_All_Faces"; + string anAllVolumesGroupName = "Group_Of_All_Volumes"; + + // Reserve four ids for families of free elements + // (1 - nodes, -1 - edges, -2 - faces, -3 - volumes). + // 'Free' means here not belonging to any group. + int aNodeFamId = FIRST_NODE_FAMILY; + int aElemFamId = FIRST_ELEM_FAMILY; + + // Process sub-meshes + map::const_iterator aSMIter = theSubMeshes.begin(); + for (; aSMIter != theSubMeshes.end(); aSMIter++) + { + list aSMFams = SplitByType((*aSMIter).second, (*aSMIter).first); + list::iterator aSMFamsIter = aSMFams.begin(); + for (; aSMFamsIter != aSMFams.end(); aSMFamsIter++) + { + DriverMED_FamilyPtr aFam2 = (*aSMFamsIter); + + list::iterator aFamsIter = aFamilies.begin(); + while (aFamsIter != aFamilies.end()) + { + DriverMED_FamilyPtr aFam1 = *aFamsIter; + list::iterator aCurrIter = aFamsIter++; + if (aFam1->myType == aFam2->myType) + { + DriverMED_FamilyPtr aCommon (new DriverMED_Family); + aFam1->Split(aFam2, aCommon); + if (!aCommon->IsEmpty()) + { + aFamilies.push_back(aCommon); + } + if (aFam1->IsEmpty()) + { + aFamilies.erase(aCurrIter); + } + if (aFam2->IsEmpty()) break; + } + } + // The rest elements of family + if (!aFam2->IsEmpty()) + { + aFamilies.push_back(aFam2); + } + } + } + + // Process groups + list::const_iterator aGroupsIter = theGroups.begin(); + for (; aGroupsIter != theGroups.end(); aGroupsIter++) + { + DriverMED_FamilyPtr aFam2 (new DriverMED_Family); + aFam2->Init(*aGroupsIter); + + list::iterator aFamsIter = aFamilies.begin(); + while (aFamsIter != aFamilies.end()) + { + DriverMED_FamilyPtr aFam1 = *aFamsIter; + list::iterator aCurrIter = aFamsIter++; + if (aFam1->myType == aFam2->myType) + { + DriverMED_FamilyPtr aCommon (new DriverMED_Family); + aFam1->Split(aFam2, aCommon); + if (!aCommon->IsEmpty()) + { + aFamilies.push_back(aCommon); + } + if (aFam1->IsEmpty()) + { + aFamilies.erase(aCurrIter); + } + if (aFam2->IsEmpty()) break; + } + } + // The rest elements of group + if (!aFam2->IsEmpty()) + { + aFamilies.push_back(aFam2); + } + } + + list::iterator aFamsIter = aFamilies.begin(); + for (; aFamsIter != aFamilies.end(); aFamsIter++) + { + DriverMED_FamilyPtr aFam = *aFamsIter; + if (aFam->myType == SMDSAbs_Node) { + aFam->SetId(aNodeFamId++); + if (doGroupOfNodes) aFam->myGroupNames.insert(anAllNodesGroupName); + } + else { + aFam->SetId(aElemFamId--); + if (aFam->myType == SMDSAbs_Edge) { + if (doGroupOfEdges) aFam->myGroupNames.insert(anAllEdgesGroupName); + } + else if (aFam->myType == SMDSAbs_Face) { + if (doGroupOfFaces) aFam->myGroupNames.insert(anAllFacesGroupName); + } + else if (aFam->myType == SMDSAbs_Volume) { + if (doGroupOfVolumes) aFam->myGroupNames.insert(anAllVolumesGroupName); + } + } + } + + // Create families for elements, not belonging to any group + if (doGroupOfNodes) + { + DriverMED_FamilyPtr aFreeNodesFam (new DriverMED_Family); + aFreeNodesFam->SetId(REST_NODES_FAMILY); + aFreeNodesFam->myType = SMDSAbs_Node; + aFreeNodesFam->myGroupNames.insert(anAllNodesGroupName); + aFamilies.push_back(aFreeNodesFam); + } + + if (doGroupOfEdges) + { + DriverMED_FamilyPtr aFreeEdgesFam (new DriverMED_Family); + aFreeEdgesFam->SetId(REST_EDGES_FAMILY); + aFreeEdgesFam->myType = SMDSAbs_Edge; + aFreeEdgesFam->myGroupNames.insert(anAllEdgesGroupName); + aFamilies.push_back(aFreeEdgesFam); + } + + if (doGroupOfFaces) + { + DriverMED_FamilyPtr aFreeFacesFam (new DriverMED_Family); + aFreeFacesFam->SetId(REST_FACES_FAMILY); + aFreeFacesFam->myType = SMDSAbs_Face; + aFreeFacesFam->myGroupNames.insert(anAllFacesGroupName); + aFamilies.push_back(aFreeFacesFam); + } + + if (doGroupOfVolumes) + { + DriverMED_FamilyPtr aFreeVolumesFam (new DriverMED_Family); + aFreeVolumesFam->SetId(REST_VOLUMES_FAMILY); + aFreeVolumesFam->myType = SMDSAbs_Volume; + aFreeVolumesFam->myGroupNames.insert(anAllVolumesGroupName); + aFamilies.push_back(aFreeVolumesFam); + } + + DriverMED_FamilyPtr aNullFam (new DriverMED_Family); + aNullFam->SetId(0); + aNullFam->myType = SMDSAbs_All; + aFamilies.push_back(aNullFam); + + return aFamilies; +} + +//============================================================================= +/*! + * Create TFamilyInfo for this family + */ +//============================================================================= +MEDA::PFamilyInfo DriverMED_Family::GetFamilyInfo + (const MEDA::PMeshInfo& theMeshInfo) const +{ + string aValue; + ostringstream aStr; + aStr << myId; + aValue = aStr.str(); + MED::TStringVector anAttrDescs (1, ""); // 1 attribute with empty description, + MED::TIntVector anAttrIds (1, myId); // Id=0, + MED::TIntVector anAttrVals (1, myId); // Value=0 + + MEDA::PFamilyInfo anInfo = MEDA::TWrapper::CrFamilyInfo(theMeshInfo, + aValue, + myId, + myGroupNames, + anAttrDescs,anAttrIds,anAttrVals); + +// cout << endl; +// cout << "Groups: "; +// set::iterator aGrIter = myGroupNames.begin(); +// for (; aGrIter != myGroupNames.end(); aGrIter++) +// { +// cout << " " << *aGrIter; +// } +// cout << endl; +// +// cout << "Elements: "; +// set::iterator anIter = myElements.begin(); +// for (; anIter != myElements.end(); anIter++) +// { +// cout << " " << (*anIter)->GetID(); +// } +// cout << endl; + + return anInfo; +} + +//============================================================================= +/*! + * Initialize the tool by SMESHDS_Group + */ +//============================================================================= +void DriverMED_Family::Init (SMESHDS_Group* group) +{ + // Elements + myElements.clear(); + group->InitIterator(); + while (group->More()) + { + myElements.insert(group->Next()); + } + + // Type + myType = group->GetType(); + + // Groups list + myGroupNames.clear(); + myGroupNames.insert(string(group->GetStoreName())); +} + +//============================================================================= +/*! + * Split on some parts (families) + * on the basis of the elements type. + */ +//============================================================================= +list DriverMED_Family::SplitByType (SMESHDS_SubMesh* theSubMesh, + const int theId) +{ + list aFamilies; + DriverMED_FamilyPtr aNodesFamily (new DriverMED_Family); + DriverMED_FamilyPtr anEdgesFamily (new DriverMED_Family); + DriverMED_FamilyPtr aFacesFamily (new DriverMED_Family); + DriverMED_FamilyPtr aVolumesFamily (new DriverMED_Family); + + char submeshGrpName[ 30 ]; + sprintf( submeshGrpName, "SubMesh %d", theId ); + + SMDS_NodeIteratorPtr aNodesIter = theSubMesh->GetNodes(); + while (aNodesIter->more()) + { + const SMDS_MeshNode* aNode = aNodesIter->next(); + aNodesFamily->AddElement(aNode); + } + + SMDS_ElemIteratorPtr anElemsIter = theSubMesh->GetElements(); + while (anElemsIter->more()) + { + const SMDS_MeshElement* anElem = anElemsIter->next(); + switch (anElem->GetType()) + { + case SMDSAbs_Edge: + anEdgesFamily->AddElement(anElem); + break; + case SMDSAbs_Face: + aFacesFamily->AddElement(anElem); + break; + case SMDSAbs_Volume: + aVolumesFamily->AddElement(anElem); + break; + default: + break; + } + } + + if (!aNodesFamily->IsEmpty()) { + aNodesFamily->SetType(SMDSAbs_Node); + aNodesFamily->AddGroupName(submeshGrpName); + aFamilies.push_back(aNodesFamily); + } + if (!anEdgesFamily->IsEmpty()) { + anEdgesFamily->SetType(SMDSAbs_Edge); + anEdgesFamily->AddGroupName(submeshGrpName); + aFamilies.push_back(anEdgesFamily); + } + if (!aFacesFamily->IsEmpty()) { + aFacesFamily->SetType(SMDSAbs_Face); + aFacesFamily->AddGroupName(submeshGrpName); + aFamilies.push_back(aFacesFamily); + } + if (!aVolumesFamily->IsEmpty()) { + aVolumesFamily->SetType(SMDSAbs_Volume); + aVolumesFamily->AddGroupName(submeshGrpName); + aFamilies.push_back(aVolumesFamily); + } + + return aFamilies; +} + +//============================================================================= +/*! + * Remove from elements, common with , + * Remove from elements, common with , + * Create family from common elements, with combined groups list. + */ +//============================================================================= +void DriverMED_Family::Split (DriverMED_FamilyPtr by, + DriverMED_FamilyPtr common) +{ + // Elements + set::iterator anIter = by->myElements.begin(); + for (; anIter != by->myElements.end(); anIter++) + { + if (myElements.find(*anIter) != myElements.end()) + { + common->myElements.insert(*anIter); + myElements.erase(*anIter); + by->myElements.erase(*anIter); + } + } + + if (!common->IsEmpty()) + { + // Groups list + common->myGroupNames = myGroupNames; + set::iterator aGrNamesIter = by->myGroupNames.begin(); + for (; aGrNamesIter != by->myGroupNames.end(); aGrNamesIter++) + { + common->myGroupNames.insert(*aGrNamesIter); + } + + // Type + common->myType = myType; + } +} diff --git a/src/DriverMED/DriverMED_Family.h b/src/DriverMED/DriverMED_Family.h new file mode 100644 index 000000000..cca2bf075 --- /dev/null +++ b/src/DriverMED/DriverMED_Family.h @@ -0,0 +1,121 @@ +// SMESH DriverMED : tool to split groups on families +// +// Copyright (C) 2003 CEA +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +// +// +// +// File : DriverMED_Family.hxx +// Author : Julia DOROVSKIKH +// Module : SMESH +// $Header$ + +#ifndef _INCLUDE_DRIVERMED_FAMILY +#define _INCLUDE_DRIVERMED_FAMILY + +#include "SMDS_Mesh.hxx" +#include "SMESHDS_Group.hxx" +#include "SMESHDS_SubMesh.hxx" +#include "MEDA_Wrapper.hxx" + +#include +#include + +using namespace std; + +#define REST_NODES_FAMILY 1 +#define REST_EDGES_FAMILY -1 +#define REST_FACES_FAMILY -2 +#define REST_VOLUMES_FAMILY -3 +#define FIRST_NODE_FAMILY 2 +#define FIRST_ELEM_FAMILY -4 + +class DriverMED_Family; +typedef boost::shared_ptr DriverMED_FamilyPtr; + +class DriverMED_Family +{ + public: + + // Methods for groups storing to MED + + static list MakeFamilies (const map & theSubMeshes, + const list& theGroups, + const bool doGroupOfNodes, + const bool doGroupOfEdges, + const bool doGroupOfFaces, + const bool doGroupOfVolumes); + // Split each group from list and each sub-mesh from list + // on some parts (families) on the basis of the elements membership in other groups + // from and other sub-meshes from . + // Resulting families have no common elements. + + MEDA::PFamilyInfo GetFamilyInfo (const MEDA::PMeshInfo& theMeshInfo) const; + // Create TFamilyInfo for this family + + const set& GetElements () const { return myElements; } + // Returns elements of this family + + int GetId () const { return myId; } + // Returns a family ID + + public: + + // Methods for groups reading from MED + + void AddElement (const SMDS_MeshElement* theElement) { myElements.insert(theElement); } + + void AddGroupName (string theGroupName) { myGroupNames.insert(theGroupName); } + + void SetType (const SMDSAbs_ElementType theType) { myType = theType; } + SMDSAbs_ElementType GetType () { return myType; } + + bool MemberOf (string theGroupName) const + { return (myGroupNames.find(theGroupName) != myGroupNames.end()); } + + const MED::TStringSet& GetGroupNames () const { return myGroupNames; } + + private: + void Init (SMESHDS_Group* group); + // Initialize the tool by SMESHDS_Group + + static list SplitByType (SMESHDS_SubMesh* theSubMesh, + const int theId); + // Split on some parts (families) + // on the basis of the elements type. + + void Split (DriverMED_FamilyPtr by, + DriverMED_FamilyPtr common); + // Remove from elements, common with , + // Remove from elements, common with , + // Create family from common elements, with combined groups list. + + void SetId (const int theId) { myId = theId; } + // Sets a family ID + + bool IsEmpty () const { return myElements.empty(); } + // Check, if this family has empty list of elements + + private: + int myId; + SMDSAbs_ElementType myType; + set myElements; + MED::TStringSet myGroupNames; +}; + +#endif diff --git a/src/DriverMED/DriverMED_R_SMESHDS_Document.cxx b/src/DriverMED/DriverMED_R_SMESHDS_Document.cxx index 4949199ab..ca50c550e 100644 --- a/src/DriverMED/DriverMED_R_SMESHDS_Document.cxx +++ b/src/DriverMED/DriverMED_R_SMESHDS_Document.cxx @@ -31,14 +31,13 @@ using namespace std; extern "C" { - void * SMESH_createMEDDocumentReader() + Document_Reader *maker() { return new DriverMED_R_SMESHDS_Document; } } DriverMED_R_SMESHDS_Document::DriverMED_R_SMESHDS_Document() - :Document_Reader(new DriverMED_R_SMESHDS_Mesh()) { ; } @@ -61,6 +60,8 @@ void DriverMED_R_SMESHDS_Document::Read() int myMeshId; + //string myFile = string("/home/home_users/cai/projects/salome_prev04/SALOME_ROOT/data/fra1.med"); + /**************************************************************************** * OUVERTURE DU FICHIER EN LECTURE * ****************************************************************************/ diff --git a/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx b/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx index 3c1475954..c37f1e60a 100644 --- a/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx +++ b/src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx @@ -24,676 +24,580 @@ // File : DriverMED_R_SMESHDS_Mesh.cxx // Module : SMESH -using namespace std; #include "DriverMED_R_SMESHDS_Mesh.h" #include "DriverMED_R_SMDS_Mesh.h" #include "utilities.h" -#include +#include "DriverMED_Family.h" -extern "C" -{ -/** - * Factory function which will be called by SMESHDriver - */ -void * SMESH_createMEDMeshReader() -{ - return new DriverMED_R_SMESHDS_Mesh(); -} +#include "SMESHDS_Group.hxx" -} +#include "MEDA_Wrapper.hxx" +#include "MED_Utilities.hxx" + +#include DriverMED_R_SMESHDS_Mesh::DriverMED_R_SMESHDS_Mesh() + : + myMesh (NULL), + myFile (""), + myFileId (-1), + myMeshId (-1) { - myFileId = -1; } DriverMED_R_SMESHDS_Mesh::~DriverMED_R_SMESHDS_Mesh() { - ; +// map::iterator aFamsIter = myFamilies.begin(); +// for (; aFamsIter != myFamilies.end(); aFamsIter++) +// { +// delete (*aFamsIter).second; +// } } void DriverMED_R_SMESHDS_Mesh::SetMesh(SMDS_Mesh * aMesh) { - //myMesh = SMESHDS_Mesh *::DownCast(aMesh); - myMesh = aMesh; + myMesh = aMesh; } void DriverMED_R_SMESHDS_Mesh::SetFile(string aFile) { - myFile = aFile; + myFile = aFile; } void DriverMED_R_SMESHDS_Mesh::SetFileId(med_idt aFileId) { - myFileId = aFileId; + myFileId = aFileId; } void DriverMED_R_SMESHDS_Mesh::SetMeshId(int aMeshId) { - myMeshId = aMeshId; + myMeshId = aMeshId; } -void DriverMED_R_SMESHDS_Mesh::Read() +void DriverMED_R_SMESHDS_Mesh::SetMeshName(string theMeshName) { + myMeshName = theMeshName; +} - string myClass = string("SMDS_Mesh"); - string myExtension = string("MED"); +void DriverMED_R_SMESHDS_Mesh::Read() +{ - DriverMED_R_SMDS_Mesh *myReader = new DriverMED_R_SMDS_Mesh; + string myClass = string("SMDS_Mesh"); + string myExtension = string("MED"); - myReader->SetMesh(myMesh); - myReader->SetMeshId(myMeshId); - myReader->SetFile(myFile); - myReader->SetFileId(-1); + DriverMED_R_SMDS_Mesh *myReader = new DriverMED_R_SMDS_Mesh; - myReader->Read(); + myReader->SetMesh(myMesh); + myReader->SetMeshId(myMeshId); + myReader->SetFile(myFile); + myReader->SetFileId(-1); + myReader->Read(); } void DriverMED_R_SMESHDS_Mesh::Add() { + string myClass = string("SMDS_Mesh"); + string myExtension = string("MED"); - string myClass = string("SMDS_Mesh"); - string myExtension = string("MED"); - - DriverMED_R_SMDS_Mesh *myReader = new DriverMED_R_SMDS_Mesh; + DriverMED_R_SMDS_Mesh *myReader = new DriverMED_R_SMDS_Mesh; - myReader->SetMesh(myMesh); - myReader->SetMeshId(myMeshId); + myReader->SetMesh(myMesh); + myReader->SetMeshId(myMeshId); - SCRUTE(myFileId); - myReader->SetFileId(myFileId); - - myReader->Read(); + SCRUTE(myFileId); + myReader->SetFileId(myFileId); + myReader->Read(); } -void DriverMED_R_SMESHDS_Mesh::ReadMySelf() -{ - med_err ret = 0; - int i, j, k, l; - int numero; - char message[200]; - bool ok; - /* nombre d'objets MED */ - char nom_universel[MED_TAILLE_LNOM + 1]; - med_int long_fichier_en_tete; - char *fichier_en_tete; - char version_hdf[10]; - char version_med[10]; - med_int nmaa, mdim, nnoe; - med_int nmai[MED_NBR_GEOMETRIE_MAILLE], nfac[MED_NBR_GEOMETRIE_FACE]; - med_int nare[MED_NBR_GEOMETRIE_ARETE]; - /* nom du maillage */ - char nommaa[MED_TAILLE_NOM + 1]; - /* noeuds */ - med_float *coo; - char nomcoo[3 * MED_TAILLE_PNOM + 1]; - char unicoo[3 * MED_TAILLE_PNOM + 1]; - char *nomnoe; - med_int *numnoe; - med_int *nufano; - med_repere rep; - med_booleen inonoe, inunoe; - med_mode_switch mode_coo; - char str[MED_TAILLE_PNOM + 1]; - /* elements */ - med_int nsup; - med_int edim; - med_int taille; - med_int elem_id; - med_int cmpt = 0; - med_int *connectivite; - char *nomele; - med_int *numele; - med_int *nufael; - med_booleen inoele, inuele; - med_connectivite typ_con; - med_geometrie_element typgeo; - med_geometrie_element typmai[MED_NBR_GEOMETRIE_MAILLE] = - { MED_POINT1, MED_SEG2, - MED_SEG3, MED_TRIA3, - MED_TRIA6, MED_QUAD4, - MED_QUAD8, MED_TETRA4, - MED_TETRA10, MED_HEXA8, - MED_HEXA20, MED_PENTA6, - MED_PENTA15, MED_PYRA5, - MED_PYRA13 - }; - med_int desmai[MED_NBR_GEOMETRIE_MAILLE] = - { 0, 2, 3, 3, 3, 4, 4, 4, 4, 6, 6, 5, 5, 5, 5 }; - med_int nmailles[MED_NBR_GEOMETRIE_MAILLE]; - char nommai[MED_NBR_GEOMETRIE_MAILLE][MED_TAILLE_NOM + 1] = { "MED_POINT1", - "MED_SEG2", - "MED_SEG3", - "MED_TRIA3", - "MED_TRIA6", - "MED_QUAD4", - "MED_QUAD8", - "MED_TETRA4", - "MED_TETRA10", - "MED_HEXA8", - "MED_HEXA20", - "MED_PENTA6", - "MED_PENTA15", - "MED_PYRA5", - "MED_PYRA13" - }; - med_geometrie_element typfac[MED_NBR_GEOMETRIE_FACE] = - { MED_TRIA3, MED_TRIA6, - MED_QUAD4, MED_QUAD8 - }; - med_int desfac[MED_NBR_GEOMETRIE_FACE] = { 3, 3, 4, 4 }; - med_int nfaces[MED_NBR_GEOMETRIE_FACE]; - char nomfac[MED_NBR_GEOMETRIE_FACE][MED_TAILLE_NOM + 1] = - { "MED_TRIA3", "MED_TRIA6", - "MED_QUAD4", "MED_QUAD8" - }; - med_geometrie_element typare[MED_NBR_GEOMETRIE_ARETE] = - { MED_SEG2, MED_SEG3 }; - med_int desare[MED_NBR_GEOMETRIE_ARETE] = { 2, 3 }; - med_int naretes[MED_NBR_GEOMETRIE_ARETE]; - char nomare[MED_NBR_GEOMETRIE_ARETE][MED_TAILLE_NOM + 1] = - { "MED_SEG2", "MED_SEG3" }; - /* familles */ - med_int nfam; - med_int natt, ngro; - char *attdes, *gro; - med_int *attval, *attide; - char nomfam[MED_TAILLE_NOM + 1]; - med_int numfam; - char str1[MED_TAILLE_DESC + 1]; - char str2[MED_TAILLE_LNOM + 1]; - string fam; - string fam_type; - string fam_id; - - char *file2Read; - bool locally_managed; - - if (myFileId == -1) - locally_managed = true; - else - locally_managed = false; - - if (locally_managed) - { - file2Read = (char *)myFile.c_str(); - myFileId = MEDouvrir(file2Read, MED_LECT); - if (myFileId < 0) - { - fprintf(stderr, ">> ERREUR : ouverture du fichier %s \n", - file2Read); - exit(EXIT_FAILURE); - } - numero = 1; - } - else - numero = myMeshId; - sprintf(nommaa, "Mesh %d", myMeshId); //pour load - SCRUTE(nommaa); - - typ_con = MED_NOD; - mode_coo = MED_FULL_INTERLACE; - mdim = 3; - - SMESHDS_Mesh * mySMESHDSMesh = dynamic_cast(myMesh); - - //TopoDS_Shape myShape = mySMESHDSMesh->ShapeToMesh(); - - /**************************************************************************** - * NOMBRES D'OBJETS MED * - ****************************************************************************/ - fprintf(stdout, "\n(****************************)\n"); - fprintf(stdout, "(* INFORMATIONS GENERALES : *)\n"); - fprintf(stdout, "(****************************)\n"); - - /* lecture du nom et de la dimension du maillage */ - /*! fprintf(stdout,"%d %d\n",myFileId,numero); - * ret = MEDmaaInfo(myFileId,numero,nommaa,&mdim); - * fprintf(stdout,"%d\n",ret); - * if (ret < 0) - * { - * fprintf(stderr,">> ERREUR : lecture du nom du maillage \n"); - * exit(EXIT_FAILURE); - * } - * fprintf(stdout,"- Nom du maillage : <<%s>>\n",nommaa); - * fprintf(stdout,"- Dimension du maillage : %d\n",mdim); - */ - /* Combien de noeuds ? */ - nnoe = - MEDnEntMaa(myFileId, nommaa, MED_COOR, MED_NOEUD, MED_POINT1, typ_con); - if (nnoe < 0) - { - fprintf(stderr, ">> ERREUR : lecture du nombre de noeuds \n"); - exit(EXIT_FAILURE); - } - fprintf(stdout, "- Nombre de noeuds : %d \n", nnoe); - - /* Combien de mailles, faces ou aretes ? */ - for (i = 0; i < MED_NBR_GEOMETRIE_MAILLE; i++) - { - nmailles[i] = - MEDnEntMaa(myFileId, nommaa, MED_CONN, MED_MAILLE, typmai[i], - typ_con); - if (nmailles[i] < 0) - { - fprintf(stderr, ">> ERREUR : lecture du nombre de mailles \n"); - exit(EXIT_FAILURE); - } - fprintf(stdout, "- Nombre de mailles de type %s : %d \n", nommai[i], - nmailles[i]); - } +static const SMDS_MeshNode* +FindNode(const SMDS_Mesh* theMesh, med_int theId){ + const SMDS_MeshNode* aNode = theMesh->FindNode(theId); + if(aNode) return aNode; + EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<> ERREUR : lecture du nombre de faces \n"); - exit(EXIT_FAILURE); - } - fprintf(stdout, "- Nombre de faces de type %s : %d \n", nomfac[i], - nfaces[i]); - } - for (i = 0; i < MED_NBR_GEOMETRIE_ARETE; i++) - { - naretes[i] = - MEDnEntMaa(myFileId, nommaa, MED_CONN, MED_ARETE, typare[i], - typ_con); - if (naretes[i] < 0) - { - fprintf(stderr, ">> ERREUR : lecture du nombre d'aretes \n"); - exit(EXIT_FAILURE); +DriverMED_R_SMESHDS_Mesh::ReadStatus DriverMED_R_SMESHDS_Mesh::ReadMySelf() +{ + ReadStatus result = DRS_FAIL; + try{ + using namespace MEDA; + + myFamilies.clear(); + MESSAGE("ReadMySelf - myFile : "<GetName()); + if(aMeshName != aMeshInfo->GetName()) continue; + result = DRS_OK; + med_int aMeshDim = aMeshInfo->GetDim(); + + // Reading MED families to the temporary structure + //------------------------------------------------ + med_int aNbFams = aMed.GetNbFamilies(aMeshInfo); + MESSAGE("Read " << aNbFams << " families"); + for (med_int iFam = 0; iFam < aNbFams; iFam++) { + PFamilyInfo aFamilyInfo = aMed.GetFamilyInfo(aMeshInfo, iFam); + med_int aFamId = aFamilyInfo->GetId(); + MESSAGE("Family " << aFamId << " :"); + +//if (aFamId >= FIRST_VALID_FAMILY) { + DriverMED_FamilyPtr aFamily (new DriverMED_Family); + + med_int aNbGrp = aFamilyInfo->GetNbGroup(); + MESSAGE("belong to " << aNbGrp << " groups"); + for (med_int iGr = 0; iGr < aNbGrp; iGr++) { + string aGroupName = aFamilyInfo->GetGroupName(iGr); + MESSAGE(aGroupName); + aFamily->AddGroupName(aGroupName); + } +// aFamily->SetId(aFamId); + myFamilies[aFamId] = aFamily; +// } + } + + // Reading MED nodes to the corresponding SMDS structure + //------------------------------------------------------ + PNodeInfo aNodeInfo = aMed.GetNodeInfo(aMeshInfo); + med_booleen anIsNodeNum = aNodeInfo->IsElemNum(); + med_int aNbElems = aNodeInfo->GetNbElem(); + MESSAGE("ReadMySelf - aNodeInfo->GetNbElem() = "<X()<<", "<Y()<<", "<Z()<GetFamNum(iElem); + if (myFamilies.find(aFamNum) != myFamilies.end()) + { + myFamilies[aFamNum]->AddElement(aNode); + myFamilies[aFamNum]->SetType(SMDSAbs_Node); + } + } + + // Reading pre information about all MED cells + //-------------------------------------------- + bool takeNumbers = true; // initially we trust the numbers from file + MED::TEntityInfo aEntityInfo = aMed.GetEntityInfo(aMeshInfo); + MED::TEntityInfo::iterator anEntityIter = aEntityInfo.begin(); + for(; anEntityIter != aEntityInfo.end(); anEntityIter++){ + const med_entite_maillage& anEntity = anEntityIter->first; + if(anEntity == MED_NOEUD) continue; + // Reading MED cells to the corresponding SMDS structure + //------------------------------------------------------ + const MED::TGeom& aTGeom = anEntityIter->second; + MED::TGeom::const_iterator anTGeomIter = aTGeom.begin(); + for(; anTGeomIter != aTGeom.end(); anTGeomIter++){ + const med_geometrie_element& aGeom = anTGeomIter->first; + if(aGeom == MED_POINT1) continue; + PCellInfo aCellInfo = aMed.GetCellInfo(aMeshInfo,anEntity,aGeom); + med_booleen anIsElemNum = takeNumbers ? aCellInfo->IsElemNum() : MED_FAUX; + med_int aNbElems = aCellInfo->GetNbElem(); + MESSAGE("ReadMySelf - anEntity = "<> ERREUR : lecture du nombre de familles \n"); - exit(EXIT_FAILURE); - } - fprintf(stdout, "- Nombre de familles : %d \n", nfam); - - vector < int >family[nfam]; - - /**************************************************************************** - * LECTURE DES NOEUDS * - ****************************************************************************/ - fprintf(stdout, "\n(************************)\n"); - fprintf(stdout, "(* NOEUDS DU MAILLAGE : *)\n"); - fprintf(stdout, "(************************)\n"); - - /* Allocations memoires */ - /* table des coordonnees - * profil : (dimension * nombre de noeuds ) */ - coo = (med_float *) malloc(sizeof(med_float) * nnoe * mdim); - /* table des numeros, des numeros de familles des noeuds - * profil : (nombre de noeuds) */ - numnoe = (med_int *) malloc(sizeof(med_int) * nnoe); - nufano = (med_int *) malloc(sizeof(med_int) * nnoe); - /* table des noms des noeuds - * profil : (nnoe*MED_TAILLE_PNOM+1) */ - nomnoe = (char *)malloc(MED_TAILLE_PNOM * nnoe + 1); - - /* lecture des noeuds : - * - coordonnees - * - noms (optionnel dans un fichier MED) - * - numeros (optionnel dans un fichier MED) - * - numeros des familles */ - ret = MEDnoeudsLire(myFileId, nommaa, mdim, coo, mode_coo, &rep, - nomcoo, unicoo, nomnoe, &inonoe, numnoe, &inunoe, nufano, nnoe); - if (ret < 0) - strcpy(message, ">> ERREUR : lecture des noeuds \n"); - - if (inunoe) - { - for (int i = 0; i < nnoe; i++) - { - ok = mySMESHDSMesh->AddNodeWithID(coo[i * 3], coo[i * 3 + 1], - coo[i * 3 + 2], numnoe[i]); - //fprintf(Out,"%d %f %f %f\n",numnoe[i],coo[i*3],coo[i*3+1],coo[i*3+2]); + }else{ + for(int i = 0; i < aNbNodes; i++){ + aNodeIds.at(i) = aCellInfo->GetConn(iElem,i); } - } - else - { - for (int i = 0; i < nnoe; i++) - { - ok = mySMESHDSMesh->AddNodeWithID(coo[i * 3], coo[i * 3 + 1], - coo[i * 3 + 2], i + 1); - //fprintf(Out,"%d %f %f %f\n",numnoe[i],coo[i*3],coo[i*3+1],i); - family[*(nufano + i)].push_back(numnoe[i]); + } + //if(anIsElemNum) + // cout<GetElemNum(iElem)<<": "; + //else + // cout<GetFamNum(iElem); + try{ + switch(aGeom){ + case MED_SEG2: + case MED_SEG3: + if(anIsElemNum) + anElement = myMesh->AddEdgeWithID(aNodeIds.at(0), + aNodeIds.at(1), + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds.at(0)), + FindNode(myMesh,aNodeIds.at(1))); + isRenum = anIsElemNum; + } + break; + case MED_TRIA3: + case MED_TRIA6: + aNbNodes = 3; + if(anIsElemNum) + anElement = myMesh->AddFaceWithID(aNodeIds.at(0), + aNodeIds.at(1), + aNodeIds.at(2), + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds.at(0)), + FindNode(myMesh,aNodeIds.at(1)), + FindNode(myMesh,aNodeIds.at(2))); + isRenum = anIsElemNum; + } + break; + case MED_QUAD4: + case MED_QUAD8: + aNbNodes = 4; + // There is some differnce between SMDS and MED + if(anIsElemNum) + anElement = myMesh->AddFaceWithID(aNodeIds.at(0), + aNodeIds.at(1), + aNodeIds.at(2), + aNodeIds.at(3), + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds.at(0)), + FindNode(myMesh,aNodeIds.at(1)), + FindNode(myMesh,aNodeIds.at(2)), + FindNode(myMesh,aNodeIds.at(3))); + isRenum = anIsElemNum; + } + break; + case MED_TETRA4: + case MED_TETRA10: + aNbNodes = 4; + if(anIsElemNum) + anElement = myMesh->AddVolumeWithID(aNodeIds.at(0), + aNodeIds.at(1), + aNodeIds.at(2), + aNodeIds.at(3), + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds.at(0)), + FindNode(myMesh,aNodeIds.at(1)), + FindNode(myMesh,aNodeIds.at(2)), + FindNode(myMesh,aNodeIds.at(3))); + isRenum = anIsElemNum; + } + break; + case MED_PYRA5: + case MED_PYRA13: + aNbNodes = 5; + // There is some differnce between SMDS and MED + if(anIsElemNum) + anElement = myMesh->AddVolumeWithID(aNodeIds.at(0), + aNodeIds.at(1), + aNodeIds.at(2), + aNodeIds.at(3), + aNodeIds.at(4), + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds.at(0)), + FindNode(myMesh,aNodeIds.at(1)), + FindNode(myMesh,aNodeIds.at(2)), + FindNode(myMesh,aNodeIds.at(3)), + FindNode(myMesh,aNodeIds.at(4))); + isRenum = anIsElemNum; + } + break; + case MED_PENTA6: + case MED_PENTA15: + aNbNodes = 6; + if(anIsElemNum) + anElement = myMesh->AddVolumeWithID(aNodeIds.at(0), + aNodeIds.at(1), + aNodeIds.at(2), + aNodeIds.at(3), + aNodeIds.at(4), + aNodeIds.at(5), + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds.at(0)), + FindNode(myMesh,aNodeIds.at(1)), + FindNode(myMesh,aNodeIds.at(2)), + FindNode(myMesh,aNodeIds.at(3)), + FindNode(myMesh,aNodeIds.at(4)), + FindNode(myMesh,aNodeIds.at(5))); + isRenum = anIsElemNum; + } + break; + case MED_HEXA8: + case MED_HEXA20: + aNbNodes = 8; + if(anIsElemNum) + anElement = myMesh->AddVolumeWithID(aNodeIds.at(0), + aNodeIds.at(1), + aNodeIds.at(2), + aNodeIds.at(3), + aNodeIds.at(4), + aNodeIds.at(5), + aNodeIds.at(6), + aNodeIds.at(7), + aCellInfo->GetElemNum(iElem)); + if (!anElement) { + anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds.at(0)), + FindNode(myMesh,aNodeIds.at(1)), + FindNode(myMesh,aNodeIds.at(2)), + FindNode(myMesh,aNodeIds.at(3)), + FindNode(myMesh,aNodeIds.at(4)), + FindNode(myMesh,aNodeIds.at(5)), + FindNode(myMesh,aNodeIds.at(6)), + FindNode(myMesh,aNodeIds.at(7))); + isRenum = anIsElemNum; + } + break; } + }catch(const std::exception& exc){ + //INFOS("Follow exception was cought:\n\t"<AddElement(anElement); + myFamilies[aFamNum]->SetType(anElement->GetType()); + } + } + } + } } + break; + } + } + }catch(const std::exception& exc){ + INFOS("Follow exception was cought:\n\t"< 0 && ret == 0) - { - /* dimension de la maille */ - edim = typmai[i] / 100; - nsup = 0; - if (mdim == 2 || mdim == 3) - if (edim == 1) - nsup = 1; - if (mdim == 3) - if (edim == 2) - nsup = 1; - - taille = nsup + typmai[i] % 100; - //taille = typmai[i]%100; - - /* allocation memoire */ - connectivite = (med_int *) malloc(sizeof(med_int) * - taille * nmailles[i]); - nomele = (char *)malloc(sizeof(char) * MED_TAILLE_PNOM * - nmailles[i] + 1); - numele = (med_int *) malloc(sizeof(med_int) * nmailles[i]); - nufael = (med_int *) malloc(sizeof(med_int) * nmailles[i]); - - /* lecture des données */ - ret = - MEDelementsLire(myFileId, nommaa, mdim, connectivite, - mode_coo, nomele, &inoele, numele, &inuele, nufael, - nmailles[i], MED_MAILLE, typmai[i], typ_con); - - switch (typmai[i]) - { - case MED_TRIA3: - { - if (inuele) - { - for (j = 0; j < nmailles[i]; j++) - { - elem_id = *(numele + j); - ok = mySMESHDSMesh->AddFaceWithID(*(connectivite + - j * (taille - nsup)), - *(connectivite + j * (taille - nsup) + 1), - *(connectivite + j * (taille - nsup) + 2), - elem_id); - //fprintf(Out,"%d %d %d %d\n",elem_id,*(connectivite+j*(taille-nsup)),*(connectivite+j*(taille-nsup)+1),*(connectivite+j*(taille-nsup)+2)); - } - } - else - { - for (j = 0; j < nmailles[i]; j++) - { - cmpt++; - ok = mySMESHDSMesh->AddFaceWithID(*(connectivite + - j * (taille)), - *(connectivite + j * (taille) + 1), - *(connectivite + j * (taille) + 2), cmpt); - //fprintf(Out,"%d %d %d %d\n",j,*(connectivite+j*(taille)),*(connectivite+j*(taille)+1),*(connectivite+j*(taille)+2)); - } - } - - break; - } - case MED_QUAD4: - { - if (inuele) - { - for (j = 0; j < nmailles[i]; j++) - { - elem_id = *(numele + j); - ok = mySMESHDSMesh->AddFaceWithID(*(connectivite + - j * (taille - nsup)), - *(connectivite + j * (taille - nsup) + 1), - *(connectivite + j * (taille - nsup) + 2), - *(connectivite + j * (taille - nsup) + 3), - elem_id); - //fprintf(Out,"%d %d %d %d\n",elem_id,*(connectivite+j*(taille-nsup)),*(connectivite+j*(taille-nsup)+1),*(connectivite+j*(taille-nsup)+2),*(connectivite+j*(taille-nsup)+3)); - } - } - else - { - for (j = 0; j < nmailles[i]; j++) - { - cmpt++; - ok = myMesh->AddFaceWithID(*(connectivite + - j * (taille)), - *(connectivite + j * (taille) + 1), - *(connectivite + j * (taille) + 2), - *(connectivite + j * (taille) + 3), cmpt); - //fprintf(Out,"%d %d %d %d\n",j,*(connectivite+j*(taille)),*(connectivite+j*(taille)+1),*(connectivite+j*(taille)+2),*(connectivite+j*(taille)+3)); - } - } - break; - } - case MED_TETRA4: - { - if (inuele) - { - for (j = 0; j < nmailles[i]; j++) - { - elem_id = *(numele + j); - ok = mySMESHDSMesh->AddVolumeWithID(*(connectivite + - j * (taille - nsup)), - *(connectivite + j * (taille - nsup) + 1), - *(connectivite + j * (taille - nsup) + 2), - *(connectivite + j * (taille - nsup) + 3), - elem_id); - //fprintf(Out,"%d %d %d %d\n",elem_id,*(connectivite+j*(taille-nsup)),*(connectivite+j*(taille-nsup)+1),*(connectivite+j*(taille-nsup)+2),*(connectivite+j*(taille-nsup)+3)); - } - } - else - { - for (j = 0; j < nmailles[i]; j++) - { - cmpt++; - ok = mySMESHDSMesh->AddVolumeWithID(*(connectivite + - j * (taille)), - *(connectivite + j * (taille) + 1), - *(connectivite + j * (taille) + 2), - *(connectivite + j * (taille) + 3), cmpt); - //fprintf(Out,"%d %d %d %d\n",j,*(connectivite+j*(taille)),*(connectivite+j*(taille)+1),*(connectivite+j*(taille)+2),*(connectivite+j*(taille)+3)); - } - } - break; - } - case MED_HEXA8: - { - if (inuele) - { - for (j = 0; j < nmailles[i]; j++) - { - elem_id = *(numele + j); - ok = mySMESHDSMesh->AddVolumeWithID(*(connectivite + - j * (taille - nsup)), - *(connectivite + j * (taille - nsup) + 1), - *(connectivite + j * (taille - nsup) + 2), - *(connectivite + j * (taille - nsup) + 3), - *(connectivite + j * (taille - nsup) + 4), - *(connectivite + j * (taille - nsup) + 5), - *(connectivite + j * (taille - nsup) + 6), - *(connectivite + j * (taille - nsup) + 7), - elem_id); - //fprintf(Out,"%d %d %d %d\n",elem_id,*(connectivite+j*(taille-nsup)),*(connectivite+j*(taille-nsup)+1),*(connectivite+j*(taille-nsup)+2),*(connectivite+j*(taille-nsup)+3),*(connectivite+j*(taille-nsup)+4),*(connectivite+j*(taille-nsup)+5),*(connectivite+j*(taille-nsup)+6),*(connectivite+j*(taille-nsup)+7)); - } - } - else - { - for (j = 0; j < nmailles[i]; j++) - { - cmpt++; - ok = mySMESHDSMesh->AddVolumeWithID(*(connectivite + - j * (taille)), - *(connectivite + j * (taille) + 1), - *(connectivite + j * (taille) + 2), - *(connectivite + j * (taille) + 3), - *(connectivite + j * (taille) + 4), - *(connectivite + j * (taille) + 5), - *(connectivite + j * (taille) + 6), - *(connectivite + j * (taille) + 7), cmpt); - //fprintf(Out,"%d %d %d %d\n",j,*(connectivite+j*(taille)),*(connectivite+j*(taille)+1),*(connectivite+j*(taille)+2),*(connectivite+j*(taille)+3),*(connectivite+j*(taille)+4),*(connectivite+j*(taille)+5),*(connectivite+j*(taille)+6),*(connectivite+j*(taille)+7)); - } - } - break; - } - default: - { - break; - } - } - - fprintf(stdout, "\n - Numéros de familles : \n"); - for (j = 0; j < nmailles[i]; j++) - fprintf(stdout, " %d ", *(nufael + j)); - - /* liberation memoire */ - free(connectivite); - free(nomele); - free(numele); - free(nufael); - } - } - - /**************************************************************************** - * LECTURE DES FAMILLES * - ****************************************************************************/ - printf("\n(*************************)\n"); - printf("(* FAMILLES DU MAILLAGE : *)\n"); - printf("(*************************)\n"); - if (ret == 0) - for (i = 0; i < nfam; i++) - { - - /* nombre de groupes */ - ngro = MEDnFam(myFileId, nommaa, i + 1, MED_GROUPE); - if (ngro < 0) - { - ret = -1; - strcpy(message, - ">> ERREUR : lecture du nombre de groupes d'une famille \n"); - } - - /* nombre d'attributs */ - if (ret == 0) - { - natt = MEDnFam(myFileId, nommaa, i + 1, MED_ATTR); - if (natt < 0) - { - ret = -1; - strcpy(message, - ">> ERREUR : lecture du nombre d'attributs d'une famille\n"); - } - } - - if (ret == 0) - fprintf(stdout, "- Famille %d a %d attributs et %d groupes \n", - i + 1, natt, ngro); - - /* nom,numero,attributs,groupes */ - if (ret == 0) - { - attide = (med_int *) malloc(sizeof(med_int) * natt); - attval = (med_int *) malloc(sizeof(med_int) * natt); - attdes = (char *)malloc(MED_TAILLE_DESC * natt + 1); - gro = (char *)malloc(MED_TAILLE_LNOM * ngro + 1); - ret = - MEDfamInfo(myFileId, nommaa, i + 1, nomfam, &numfam, attide, - attval, attdes, &natt, gro, &ngro); - - fam = string(nomfam); - fam_type = fam.substr(1, 1); - fam_id = fam.substr(2, 1); - if ((fam_type == string("V")) || (fam_type == string("A")) || - (fam_type == string("F"))) - LinkMeshToShape(fam_type, fam_id, family[i]); - - fprintf(stdout, " - Famille de nom %s et de numero %d : \n", - nomfam, numfam); - fprintf(stdout, " - Attributs : \n"); - for (j = 0; j < natt; j++) - { - strncpy(str1, attdes + j * MED_TAILLE_DESC, - MED_TAILLE_DESC); - str1[MED_TAILLE_DESC] = '\0'; - fprintf(stdout, " ide = %d - val = %d - des = %s\n", - *(attide + j), *(attval + j), str1); - } - free(attide); - free(attval); - free(attdes); - fprintf(stdout, " - Groupes :\n"); - for (j = 0; j < ngro; j++) - { - strncpy(str2, gro + j * MED_TAILLE_LNOM, MED_TAILLE_LNOM); - str2[MED_TAILLE_LNOM] = '\0'; - fprintf(stdout, " gro = %s\n", str2); - } - free(gro); - } - } - - if (locally_managed) - ret = MEDfermer(myFileId); - +list DriverMED_R_SMESHDS_Mesh::GetMeshNames() +{ + list aMeshNames; + + try { + using namespace MEDA; + + MESSAGE("GetMeshNames - myFile : " << myFile); + TWrapper aMed (myFile); + + if (med_int aNbMeshes = aMed.GetNbMeshes()) { + for (int iMesh = 0; iMesh < aNbMeshes; iMesh++) { + // Reading the MED mesh + //--------------------- + PMeshInfo aMeshInfo = aMed.GetMeshInfo(iMesh); + aMeshNames.push_back(aMeshInfo->GetName()); + } + } + }catch(const std::exception& exc){ + INFOS("Follow exception was cought:\n\t"<myNodes) +list DriverMED_R_SMESHDS_Mesh::GetGroupNames() { + list aResult; + set aResGroupNames; + + map::iterator aFamsIter = myFamilies.begin(); + for (; aFamsIter != myFamilies.end(); aFamsIter++) + { + DriverMED_FamilyPtr aFamily = (*aFamsIter).second; + const MED::TStringSet& aGroupNames = aFamily->GetGroupNames(); + set::iterator aGrNamesIter = aGroupNames.begin(); + for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++) + { + string aName = *aGrNamesIter; + // Check, if this is a Group or SubMesh name +//if (aName.substr(0, 5) == string("Group")) { + if (aResGroupNames.find(aName) == aResGroupNames.end()) { + aResGroupNames.insert(aName); + aResult.push_back(aName); + } +// } + } + } + + return aResult; +} - SMESHDS_Mesh * mySMESHDSMesh = dynamic_cast(myMesh); +void DriverMED_R_SMESHDS_Mesh::GetGroup(SMESHDS_Group* theGroup) +{ + string aGroupName (theGroup->GetStoreName()); + MESSAGE("Get Group " << aGroupName); + + map::iterator aFamsIter = myFamilies.begin(); + for (; aFamsIter != myFamilies.end(); aFamsIter++) + { + DriverMED_FamilyPtr aFamily = (*aFamsIter).second; + if (aFamily->MemberOf(aGroupName)) + { + const set& anElements = aFamily->GetElements(); + set::iterator anElemsIter = anElements.begin(); + for (; anElemsIter != anElements.end(); anElemsIter++) + { + theGroup->SMDS_MeshGroup::Add(*anElemsIter); + } + } + } +} - int id = atoi(fam_id.c_str()); - if (fam_type == string("V")) - { //Linked to a vertex - for (int i = 0; i < myNodes.size(); i++) - { - const SMDS_MeshNode * node = mySMESHDSMesh->FindNode(myNodes[i]); - //const TopoDS_Vertex& S;//le recuperer !!! - //mySMESHDSMesh->SetNodeOnVertex (node,S); - } - } - else if (fam_type == string("E")) - { //Linked to an edge - for (int i = 0; i < myNodes.size(); i++) - { - const SMDS_MeshNode * node = mySMESHDSMesh->FindNode(myNodes[i]); - //const TopoDS_Edge& S;//le recuperer !!! - //mySMESHDSMesh->SetNodeOnEdge (node,S); - } - } - else if (fam_type == string("F")) - { //Linked to a face - for (int i = 0; i < myNodes.size(); i++) - { - const SMDS_MeshNode * node = mySMESHDSMesh->FindNode(myNodes[i]); - //const TopoDS_Face& S;//le recuperer !!! - //mySMESHDSMesh->SetNodeOnFace (node,S); - } - } +void DriverMED_R_SMESHDS_Mesh::GetSubMesh (SMESHDS_SubMesh* theSubMesh, + const int theId) +{ + char submeshGrpName[ 30 ]; + sprintf( submeshGrpName, "SubMesh %d", theId ); + string aName (submeshGrpName); + map::iterator aFamsIter = myFamilies.begin(); + for (; aFamsIter != myFamilies.end(); aFamsIter++) + { + DriverMED_FamilyPtr aFamily = (*aFamsIter).second; + if (aFamily->MemberOf(aName)) + { + const set& anElements = aFamily->GetElements(); + set::iterator anElemsIter = anElements.begin(); + if (aFamily->GetType() == SMDSAbs_Node) + { + for (; anElemsIter != anElements.end(); anElemsIter++) + { + const SMDS_MeshNode* node = static_cast(*anElemsIter); + theSubMesh->AddNode(node); + } + } + else + { + for (; anElemsIter != anElements.end(); anElemsIter++) + { + theSubMesh->AddElement(*anElemsIter); + } + } + } + } +} +void DriverMED_R_SMESHDS_Mesh::CreateAllSubMeshes () +{ + SMESHDS_Mesh* aSMESHDSMesh = dynamic_cast(myMesh); + if (!aSMESHDSMesh) { + EXCEPTION(runtime_error,"Can not cast SMDS_Mesh to SMESHDS_Mesh"); + } + map::iterator aFamsIter = myFamilies.begin(); + for (; aFamsIter != myFamilies.end(); aFamsIter++) + { + DriverMED_FamilyPtr aFamily = (*aFamsIter).second; + MED::TStringSet aGroupNames = aFamily->GetGroupNames(); + set::iterator aGrNamesIter = aGroupNames.begin(); + for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++) + { + string aName = *aGrNamesIter; + // Check, if this is a Group or SubMesh name + if (aName.substr(0, 7) == string("SubMesh")) + { + int Id = atoi(string(aName).substr(7).c_str()); + set anElements = aFamily->GetElements(); + set::iterator anElemsIter = anElements.begin(); + if (aFamily->GetType() == SMDSAbs_Node) + { + for (; anElemsIter != anElements.end(); anElemsIter++) + { + const SMDS_MeshNode* node = static_cast(*anElemsIter); + aSMESHDSMesh->SetNodeInVolume(node, Id); +// aSMESHDSMesh->SetNodeOnFace(node, Id); +// aSMESHDSMesh->SetNodeOnEdge(node, Id); +// aSMESHDSMesh->SetNodeOnVertex(node, Id); + } + } + else + { + for (; anElemsIter != anElements.end(); anElemsIter++) + { + aSMESHDSMesh->SetMeshElementOnShape(*anElemsIter, Id); + } + } + } + } + } } diff --git a/src/DriverMED/DriverMED_R_SMESHDS_Mesh.h b/src/DriverMED/DriverMED_R_SMESHDS_Mesh.h index 88ae5037c..c592c3034 100644 --- a/src/DriverMED/DriverMED_R_SMESHDS_Mesh.h +++ b/src/DriverMED/DriverMED_R_SMESHDS_Mesh.h @@ -29,34 +29,60 @@ #include "SMESHDS_Mesh.hxx" #include "Mesh_Reader.h" +#include "DriverMED_Family.h" -#include +#include extern "C" { #include } +using namespace std; + +class SMESHDS_Group; +class SMESHDS_SubMesh; + class DriverMED_R_SMESHDS_Mesh:public Mesh_Reader { + public: + + DriverMED_R_SMESHDS_Mesh(); + ~DriverMED_R_SMESHDS_Mesh(); + + enum ReadStatus { + DRS_OK, + DRS_EMPTY, // a MED file contains no mesh with the given name + DRS_WARN_RENUMBER, // a MED file has overlapped ranges of element numbers, + // so the numbers from the file are ignored + DRS_WARN_SKIP_ELEM, // some elements were skipped due to incorrect file data + DRS_FAIL // general failure (exception etc.) + }; + + void Read(); + ReadStatus ReadMySelf(); + void Add(); - public:DriverMED_R_SMESHDS_Mesh(); - ~DriverMED_R_SMESHDS_Mesh(); + list GetGroupNames(); + void GetGroup(SMESHDS_Group* theGroup); + void CreateAllSubMeshes(); + void GetSubMesh(SMESHDS_SubMesh* theSubMesh, const int theId); - void Read(); - void ReadMySelf(); - void Add(); + list GetMeshNames(); - void SetMesh(SMDS_Mesh * aMesh); - void SetFile(string); - void SetFileId(med_idt); - void SetMeshId(int); + void SetMesh(SMDS_Mesh * aMesh); + void SetFile(string); + void SetFileId(med_idt); + void SetMeshId(int); + void SetMeshName(string theMeshName); - void LinkMeshToShape(string, string, vector < int >); + private: - private: SMDS_Mesh * myMesh; - string myFile; - med_idt myFileId; - int myMeshId; + SMDS_Mesh * myMesh; + string myFile; + med_idt myFileId; + int myMeshId; + string myMeshName; + map myFamilies; }; #endif diff --git a/src/DriverMED/DriverMED_W_SMDS_Mesh.cxx b/src/DriverMED/DriverMED_W_SMDS_Mesh.cxx index fd6f3db75..eaa287e3b 100644 --- a/src/DriverMED/DriverMED_W_SMDS_Mesh.cxx +++ b/src/DriverMED/DriverMED_W_SMDS_Mesh.cxx @@ -207,7 +207,7 @@ void DriverMED_W_SMDS_Mesh::Write() for (i = 0; i < MED_NBR_GEOMETRIE_MAILLE; i++) nmailles[i] = 0; - SMDS_Iterator * itFaces=myMesh->facesIterator(); + SMDS_FaceIteratorPtr itFaces=myMesh->facesIterator(); int nb_of_nodes, nb_of_faces; nb_of_faces = myMesh->NbFaces(); //SCRUTE(nb_of_faces); @@ -251,7 +251,7 @@ void DriverMED_W_SMDS_Mesh::Write() } - SMDS_Iterator * itVolumes=myMesh->volumesIterator(); + SMDS_VolumeIteratorPtr itVolumes=myMesh->volumesIterator(); while(itVolumes->more()) { const SMDS_MeshVolume * elem = itVolumes->next(); @@ -295,7 +295,7 @@ void DriverMED_W_SMDS_Mesh::Write() nomnoe = ""; i = 0; - SMDS_Iterator * itNodes=myMesh->nodesIterator(); + SMDS_NodeIteratorPtr itNodes=myMesh->nodesIterator(); while(itNodes->more()) { const SMDS_MeshNode * node = itNodes->next(); @@ -370,8 +370,7 @@ void DriverMED_W_SMDS_Mesh::Write() //elem_id=*(numele+j); //fprintf(stdout,"%d \n",myId); - SMDS_Iterator * itNode= - elem->nodesIterator(); + SMDS_ElemIteratorPtr itNode= elem->nodesIterator(); while(itNode->more()) { diff --git a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx index 8b1567f02..5b77395aa 100644 --- a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx +++ b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx @@ -24,678 +24,512 @@ // File : DriverMED_W_SMESHDS_Mesh.cxx // Module : SMESH -using namespace std; #include "DriverMED_W_SMESHDS_Mesh.h" #include "DriverMED_W_SMDS_Mesh.h" +#include "DriverMED_Family.h" + #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" -#include -#include #include "utilities.h" -extern "C" -{ -/** - * Factory function which will be called by SMESHDriver - */ -void * SMESH_createMEDMeshWriter() -{ - return new DriverMED_W_SMESHDS_Mesh(); -} +#include "MEDA_Wrapper.hxx" +#include -} +#include "MED_Utilities.hxx" DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh() + : + myMesh (NULL), + myFile (""), + myFileId (-1), + myMeshId (-1), + myAllSubMeshes (false), + myDoGroupOfNodes (false), + myDoGroupOfEdges (false), + myDoGroupOfFaces (false), + myDoGroupOfVolumes (false) { - ; } DriverMED_W_SMESHDS_Mesh::~DriverMED_W_SMESHDS_Mesh() { - ; } void DriverMED_W_SMESHDS_Mesh::SetMesh(SMDS_Mesh * aMesh) { - myMesh = aMesh; + myMesh = aMesh; } void DriverMED_W_SMESHDS_Mesh::SetFile(string aFile) { - myFile = aFile; + myFile = aFile; } void DriverMED_W_SMESHDS_Mesh::SetFileId(med_idt aFileId) { - myFileId = aFileId; + myFileId = aFileId; } void DriverMED_W_SMESHDS_Mesh::SetMeshId(int aMeshId) { - myMeshId = aMeshId; + myMeshId = aMeshId; } -void DriverMED_W_SMESHDS_Mesh::Write() +void DriverMED_W_SMESHDS_Mesh::SetMeshName(string theMeshName) { - Add(); + myMeshName = theMeshName; } -void DriverMED_W_SMESHDS_Mesh::Add() +void DriverMED_W_SMESHDS_Mesh::AddGroup(SMESHDS_Group* theGroup) { + myGroups.push_back(theGroup); +} - med_err ret = 0; - int i, j, k, l; - int numero; - char message[200]; - bool ok; - /* nombre d'objets MED */ - char nom_universel[MED_TAILLE_LNOM + 1]; - med_int long_fichier_en_tete; - char *fichier_en_tete; - char version_hdf[10]; - char version_med[10]; - med_int nmaa, mdim, nnoe; - med_int nmai[MED_NBR_GEOMETRIE_MAILLE], nfac[MED_NBR_GEOMETRIE_FACE]; - med_int nare[MED_NBR_GEOMETRIE_ARETE]; - /* nom du maillage */ - char nommaa[MED_TAILLE_NOM + 1]; - /* noeuds */ - med_float *coo; - // PN : Initilialisation de nomcoo et unicoo pour lisibilite du maillage - char nomcoo[3 * MED_TAILLE_PNOM + 1] = "x y z "; - char unicoo[3 * MED_TAILLE_PNOM + 1] = "m m m "; - char *nomnoe; - med_int *numnoe; - med_int *nufano; - med_repere rep; - med_booleen inonoe, inunoe; - med_mode_switch mode_coo; - char str[MED_TAILLE_PNOM + 1]; - med_int nbNodes; - /* elements */ - med_int nsup; - med_int edim; - med_int taille; - med_int elem_id, myId; - med_int *connectivite; - char *nomele; - med_int *numele; - med_int *nufael; - med_booleen inoele, inuele; - med_connectivite typ_con; - med_geometrie_element typgeo; - med_geometrie_element typmai[MED_NBR_GEOMETRIE_MAILLE] = - { MED_POINT1, MED_SEG2, - MED_SEG3, MED_TRIA3, - MED_TRIA6, MED_QUAD4, - MED_QUAD8, MED_TETRA4, - MED_TETRA10, MED_HEXA8, - MED_HEXA20, MED_PENTA6, - MED_PENTA15, MED_PYRA5, - MED_PYRA13 - }; - med_int desmai[MED_NBR_GEOMETRIE_MAILLE] = - { 0, 2, 3, 3, 3, 4, 4, 4, 4, 6, 6, 5, 5, 5, 5 }; - med_int nmailles[MED_NBR_GEOMETRIE_MAILLE]; - char nommai[MED_NBR_GEOMETRIE_MAILLE][MED_TAILLE_NOM + 1] = { "MED_POINT1", - "MED_SEG2", - "MED_SEG3", - "MED_TRIA3", - "MED_TRIA6", - "MED_QUAD4", - "MED_QUAD8", - "MED_TETRA4", - "MED_TETRA10", - "MED_HEXA8", - "MED_HEXA20", - "MED_PENTA6", - "MED_PENTA15", - "MED_PYRA5", - "MED_PYRA13" - }; - med_geometrie_element typfac[MED_NBR_GEOMETRIE_FACE] = - { MED_TRIA3, MED_TRIA6, - MED_QUAD4, MED_QUAD8 - }; - med_int desfac[MED_NBR_GEOMETRIE_FACE] = { 3, 3, 4, 4 }; - med_int nfaces[MED_NBR_GEOMETRIE_FACE]; - char nomfac[MED_NBR_GEOMETRIE_FACE][MED_TAILLE_NOM + 1] = - { "MED_TRIA3", "MED_TRIA6", - "MED_QUAD4", "MED_QUAD8" - }; - med_geometrie_element typare[MED_NBR_GEOMETRIE_ARETE] = - { MED_SEG2, MED_SEG3 }; - med_int desare[MED_NBR_GEOMETRIE_ARETE] = { 2, 3 }; - med_int naretes[MED_NBR_GEOMETRIE_ARETE]; - char nomare[MED_NBR_GEOMETRIE_ARETE][MED_TAILLE_NOM + 1] = - { "MED_SEG2", "MED_SEG3" }; - - typ_con = MED_NOD; - mode_coo = MED_FULL_INTERLACE; - numero = myMeshId; - - //---- provisoire : switch pour ecrire les familles de mailles - int besoinfamilledemaille = 1; - //---- provisoire : switch pour ecrire les familles de mailles - - /**************************************************************************** - * OUVERTURE DU FICHIER EN ECRITURE * - ****************************************************************************/ - char *file2Read = (char *)myFile.c_str(); - - MESSAGE(" file2Read " << file2Read) - myFileId = MEDouvrir(file2Read, MED_REMP); - if (myFileId < 0) - { - fprintf(stderr, ">> ERREUR : ouverture du fichier %s \n", file2Read); - exit(EXIT_FAILURE); - } - - /**************************************************************************** - * NOMBRES D'OBJETS MED * - ****************************************************************************/ - MESSAGE("(****************************)"); - MESSAGE("(* INFORMATIONS GENERALES : *)"); - MESSAGE("(****************************)"); - - /* calcul de la dimension */ - mdim = 2; - double epsilon = 0.00001; - double nodeRefX; - double nodeRefY; - double nodeRefZ; - - bool dimX = true; - bool dimY = true; - bool dimZ = true; - - int inode = 0; - SMDS_Iterator * myItNodes=myMesh->nodesIterator(); - while(myItNodes->more()) - { - const SMDS_MeshNode * node = myItNodes->next(); - if (inode == 0) - { - nodeRefX = fabs(node->X()); - nodeRefY = fabs(node->Y()); - nodeRefZ = fabs(node->Z()); - } - SCRUTE(inode); - SCRUTE(nodeRefX); - SCRUTE(nodeRefY); - SCRUTE(nodeRefZ); - - if (inode != 0) - { - if ((fabs(fabs(node->X()) - nodeRefX) > epsilon) && dimX) - dimX = false; - if ((fabs(fabs(node->Y()) - nodeRefY) > epsilon) && dimY) - dimY = false; - if ((fabs(fabs(node->Z()) - nodeRefZ) > epsilon) && dimZ) - dimZ = false; - } - if (!dimX && !dimY && !dimZ) - { - mdim = 3; - break; - } - inode++; - } - - if (mdim != 3) - { - if (dimX && dimY && dimZ) - mdim = 0; - else if (!dimX) - { - if (dimY && dimZ) - mdim = 1; - else if ((dimY && !dimZ) || (!dimY && dimZ)) - mdim = 2; - } - else if (!dimY) - { - if (dimX && dimZ) - mdim = 1; - else if ((dimX && !dimZ) || (!dimX && dimZ)) - mdim = 2; - } - else if (!dimZ) - { - if (dimY && dimX) - mdim = 1; - else if ((dimY && !dimX) || (!dimY && dimX)) - mdim = 2; - } - } - - MESSAGE(" mdim " << mdim); - - /* creation du maillage */ - //mdim=3; - sprintf(nommaa, "Mesh %d", numero); - SCRUTE(nommaa); - ret = MEDmaaCr(myFileId, nommaa, mdim); - - ASSERT(ret == 0); - SCRUTE(ret); - - /* Combien de noeuds ? */ - nnoe = myMesh->NbNodes(); - //SCRUTE(nnoe); - /* Combien de mailles, faces ou aretes ? */ - for (i = 0; i < MED_NBR_GEOMETRIE_MAILLE; i++) - nmailles[i] = 0; - - int nb_of_nodes, nb_of_faces, nb_of_edges; - vector < int >elem_Id[MED_NBR_GEOMETRIE_MAILLE]; - - nb_of_edges = myMesh->NbEdges(); - SMDS_Iterator * itEdges=myMesh->edgesIterator(); - while(itEdges->more()) - { - const SMDS_MeshEdge * elem = itEdges->next(); - - nb_of_nodes = elem->NbNodes(); - - switch (nb_of_nodes) - { - case 2: - { - elem_Id[1].push_back(elem->GetID()); - nmailles[1]++; - break; - } - case 3: - { - elem_Id[2].push_back(elem->GetID()); - nmailles[2]++; - break; - } - } - } - - nb_of_faces = myMesh->NbFaces(); - SMDS_Iterator * itFaces=myMesh->facesIterator(); - while(itFaces->more()) - { - const SMDS_MeshElement * elem = itFaces->next(); - - nb_of_nodes = elem->NbNodes(); - - switch (nb_of_nodes) - { - case 3: - { - elem_Id[3].push_back(elem->GetID()); - nmailles[3]++; - break; - } - case 4: - { - elem_Id[5].push_back(elem->GetID()); - nmailles[5]++; - break; - } - case 6: - { - elem_Id[4].push_back(elem->GetID()); - nmailles[4]++; - break; - } - } - - } - - SMDS_Iterator * itVolumes=myMesh->volumesIterator(); - while(itVolumes->more()) - { - const SMDS_MeshElement * elem = itVolumes->next(); - - nb_of_nodes = elem->NbNodes(); - switch (nb_of_nodes) - { - case 8: - { - elem_Id[9].push_back(elem->GetID()); - nmailles[9]++; - break; - } - case 4 : - { - elem_Id[7].push_back(elem->GetID()); - nmailles[7]++; - break; - } - } - } - - /**************************************************************************** - * ECRITURE DES NOEUDS * - ****************************************************************************/ - MESSAGE("(************************)"); - MESSAGE("(* NOEUDS DU MAILLAGE : *)"); - MESSAGE("(************************)"); - - /* Allocations memoires */ - /* table des coordonnees - * profil : (dimension * nombre de noeuds ) */ - coo = (med_float *) malloc(sizeof(med_float) * nnoe * mdim); - /* table des numeros, des numeros de familles des noeuds - * profil : (nombre de noeuds) */ - numnoe = (med_int *) malloc(sizeof(med_int) * nnoe); - nufano = (med_int *) malloc(sizeof(med_int) * nnoe); - /* table des noms des noeuds - * profil : (nnoe*MED_TAILLE_PNOM+1) */ - nomnoe = ""; - - /* PN pour aster, il faut une famille 0 pour les noeuds et une autre pour les elements */ - /* PN : Creation de la famille 0 */ - char *nomfam = "FAMILLE_0"; - char *attdes = ""; - char *gro = 0; - med_int ngro = 0; - med_int natt = 1; - med_int attide = 0; - med_int attval = 0; - med_int numfam = 0; - med_int attvalabs = 1; - ret = - MEDfamCr(myFileId, nommaa, nomfam, numfam, &attide, &attval, attdes, - natt, gro, ngro); - ASSERT(ret == 0); - - /* PN : FIN Creation de la famille 0 */ - - map < int, int >mapNoeud; - typedef pair < set < int >::iterator, bool > IsFamily; - int nbFamillesNoeud; - - i = 0; - set < int >FamilySet; - nbFamillesNoeud = 0; - int verifienbnoeuds = 0; - med_int *rien = 0; - - SMDS_Iterator * itNodes=myMesh->nodesIterator(); - while(itNodes->more()) - { - const SMDS_MeshNode * node = itNodes->next(); - - if (mdim == 3) - { - coo[i * 3] = node->X(); - coo[i * 3 + 1] = node->Y(); - coo[i * 3 + 2] = node->Z(); - } - else if (mdim == 2) - { - if (dimX) - { - coo[i * 2] = node->Y(); - coo[i * 2 + 1] = node->Z(); - } - if (dimY) - { - coo[i * 2] = node->X(); - coo[i * 2 + 1] = node->Z(); - } - if (dimZ) - { - coo[i * 2] = node->X(); - coo[i * 2 + 1] = node->Y(); - } - } - else - { - if (dimX) - { - coo[i * 2] = node->Y(); - coo[i * 2 + 1] = node->Z(); - } - if (dimY) - { - coo[i * 2] = node->X(); - coo[i * 2 + 1] = node->Z(); - } - if (dimZ) - { - coo[i * 2] = node->X(); - coo[i * 2 + 1] = node->Y(); - } - } - mapNoeud[node->GetID()] = i + 1; - - // renvoie 0 pour les noeuds internes du volume - int numfamille = node->GetPosition()->GetShapeId(); - nufano[i] = numfamille; - - //SCRUTE(i); - //SCRUTE(nufano[i]); - //SCRUTE(coo[i*3]); - //SCRUTE(coo[i*3+1]); - //SCRUTE(coo[i*3+2]); - if (nufano[i] != 0) - { - IsFamily deja = FamilySet.insert(nufano[i]); // insert if new, or gives existant - if (deja.second) // actually inserted - { - char famille[MED_TAILLE_NOM + 1]; - sprintf(famille, "F%d", nufano[i]); - // CreateFamily(strdup(nommaa),strdup(famille),nufano[i],attvalabs++); - attvalabs++; - CreateFamily(strdup(nommaa), strdup(famille), nufano[i], - numfamille); - //MESSAGE("---famille-noeud--- "<(myMesh); - map mapFamille; - - if(!mySMESHDSMesh->ShapeToMesh().IsNull()) - { - TopTools_IndexedMapOfShape myIndexToShape; - TopExp::MapShapes(mySMESHDSMesh->ShapeToMesh(), myIndexToShape); - - - if (besoinfamilledemaille == 1) - { - int t; - for (t = 1; t <= myIndexToShape.Extent(); t++) - { - const TopoDS_Shape S = myIndexToShape(t); - if (mySMESHDSMesh->HasMeshElements(S)) - { - //MESSAGE ("********* Traitement de la Famille "<<-t); - - SMESHDS_SubMesh * SM = mySMESHDSMesh->MeshElements(S); - SMDS_Iterator * ite=SM->GetElements(); - bool plein = false; - while(ite->more()) - { - mapFamille[ite->next()->GetID()] = -t; - plein = true; - } - if (plein) - { - nbFamillesElts++; - char famille[MED_TAILLE_NOM + 1]; - sprintf(famille, "E%d", t); - CreateFamily(strdup(nommaa), strdup(famille), -t, - attvalabs++); - } - } - } - } - } - else besoinfamilledemaille = 0; - - int indice = 1; - for (i = 0; i < MED_NBR_GEOMETRIE_MAILLE; i++) - { - if (nmailles[i] > 0 && ret == 0) - { - MESSAGE(" Start " << typmai[i]); - - /* dimension de la maille */ - edim = typmai[i] / 100; - nsup = 0; - if (mdim == 2 || mdim == 3) - if (edim == 1) - nsup = 1; - if (mdim == 3) - if (edim == 2) - nsup = 1; - //SCRUTE(nsup); - - taille = nsup + typmai[i] % 100; - //SCRUTE(taille); - - /* allocation memoire */ - connectivite = - (med_int *) malloc(sizeof(med_int) * taille * nmailles[i]); - /* nomele = - (char *)malloc(sizeof(char) * MED_TAILLE_PNOM * - nmailles[i] + 1);*/ - nomele = ""; - numele = (med_int *) malloc(sizeof(med_int) * nmailles[i]); - nufael = (med_int *) malloc(sizeof(med_int) * nmailles[i]); - nbNodes = typmai[i] % 100; - - for (j = 0; j < nmailles[i]; j++) - { - myId = elem_Id[i][j]; - const SMDS_MeshElement * elem = - myMesh->FindElement(myId); - //*(numele+j) = myId; - *(numele + j) = indice++; - - SMDS_Iterator * itk=elem->nodesIterator(); - for (k = 0; itk->more(); k++) - { - *(connectivite + j * taille + k) = - mapNoeud[itk->next()->GetID()]; - } - delete itk; - - if (nsup) - *(connectivite + j * taille + nbNodes) = 0; - - if (besoinfamilledemaille == 1) - { - if (mapFamille.find(myId) != mapFamille.end()) - { - nufael[j] = mapFamille[myId]; - } - else - { - nufael[j] = 0; - } - } - else - { - nufael[j] = 0; - } - - //SCRUTE(myId); - //SCRUTE(j); - //SCRUTE(nufael[j]); - } - - /* ecriture des données */ - - med_int *rien = 0; - ret = - MEDelementsEcr(myFileId, nommaa, mdim, connectivite, - mode_coo, nomele, MED_FAUX, numele, MED_VRAI, nufael, - nmailles[i], MED_MAILLE, typmai[i], typ_con, MED_REMP); - ASSERT(ret == 0); - //SCRUTE(ret); - - if (ret < 0) - MESSAGE(">> ERREUR : ecriture des mailles \n"); - - /* liberation memoire */ - free(connectivite); - free(numele); - free(nufael); - MESSAGE(" End " << typmai[i]); - } - }; - MESSAGE("--- Creation de " << nbFamillesElts << " familles d elements"); +void DriverMED_W_SMESHDS_Mesh::AddAllSubMeshes() +{ + myAllSubMeshes = true; +} - } +void DriverMED_W_SMESHDS_Mesh::AddSubMesh(SMESHDS_SubMesh* theSubMesh, int theID) +{ + mySubMeshes[theID] = theSubMesh; +} - /**************************************************************************** - * FERMETURE DU FICHIER * - ****************************************************************************/ +void DriverMED_W_SMESHDS_Mesh::AddGroupOfNodes() +{ + myDoGroupOfNodes = true; +} - ret = MEDfermer(myFileId); +void DriverMED_W_SMESHDS_Mesh::AddGroupOfEdges() +{ + myDoGroupOfEdges = true; +} - if (ret != 0) - fprintf(stderr, ">> ERREUR : erreur a la fermeture du fichier %s\n", - file2Read); - MESSAGE("fichier ferme"); +void DriverMED_W_SMESHDS_Mesh::AddGroupOfFaces() +{ + myDoGroupOfFaces = true; +} +void DriverMED_W_SMESHDS_Mesh::AddGroupOfVolumes() +{ + myDoGroupOfVolumes = true; } -void DriverMED_W_SMESHDS_Mesh::CreateFamily(char *nommaa, char *famille, int i, - med_int k) +void DriverMED_W_SMESHDS_Mesh::Write() { + string myClass = string("SMDS_Mesh"); + string myExtension = string("MED"); - med_int ngro = 0; - med_int natt; + DriverMED_W_SMDS_Mesh *myWriter = new DriverMED_W_SMDS_Mesh; - natt = 1; - char attdes[MED_TAILLE_DESC + 1]; - char gro[MED_TAILLE_LNOM + 1]; - char fam2[MED_TAILLE_LNOM + 1]; + myWriter->SetMesh(myMesh); + // myWriter->SetFile(myFile); + myWriter->SetMeshId(myMeshId); + myWriter->SetFileId(myFileId); - strcpy(attdes, ""); - strcpy(gro, ""); - strcpy(fam2, famille); + myWriter->Write(); +} - med_int *attide = new med_int[1]; - med_int *attval = new med_int[1]; - attide[0] = k; - attval[0] = k; +void DriverMED_W_SMESHDS_Mesh::Add() +{ + if (myMesh->hasConstructionEdges() || myMesh->hasConstructionFaces()) { + INFOS("SMDS_MESH with hasConstructionEdges() or hasConstructionFaces() do not supports!!!"); + return; + } + try{ + using namespace MEDA; + using namespace boost; + + MESSAGE("Add - myFile : "<GetName()); + aMed.SetMeshInfo(aMeshInfo); + + // Storing SMDS groups and sub-meshes + //----------------------------------- + int myNodesDefaultFamilyId = 0; + int myEdgesDefaultFamilyId = 0; + int myFacesDefaultFamilyId = 0; + int myVolumesDefaultFamilyId = 0; + if (myDoGroupOfNodes) + myNodesDefaultFamilyId = REST_NODES_FAMILY; + if (myDoGroupOfEdges) + myEdgesDefaultFamilyId = REST_EDGES_FAMILY; + if (myDoGroupOfFaces) + myFacesDefaultFamilyId = REST_FACES_FAMILY; + if (myDoGroupOfVolumes) + myVolumesDefaultFamilyId = REST_VOLUMES_FAMILY; + + MESSAGE("Add - aFamilyInfo"); + map anElemFamMap; + list aFamilies; + if (myAllSubMeshes) { + SMESHDS_Mesh* aSMESHDSMesh = dynamic_cast(myMesh); + if (!aSMESHDSMesh) { + EXCEPTION(runtime_error,"Can not cast SMDS_Mesh to SMESHDS_Mesh"); + } + aFamilies = DriverMED_Family::MakeFamilies + (aSMESHDSMesh->SubMeshes(), myGroups, + myDoGroupOfNodes, myDoGroupOfEdges, myDoGroupOfFaces, myDoGroupOfVolumes); + } else { + aFamilies = DriverMED_Family::MakeFamilies + (mySubMeshes, myGroups, + myDoGroupOfNodes, myDoGroupOfEdges, myDoGroupOfFaces, myDoGroupOfVolumes); + } + list::iterator aFamsIter = aFamilies.begin(); + + for (; aFamsIter != aFamilies.end(); aFamsIter++) + { + PFamilyInfo aFamilyInfo = (*aFamsIter)->GetFamilyInfo(aMeshInfo); + aMed.SetFamilyInfo(aFamilyInfo); + int aFamId = (*aFamsIter)->GetId(); + + const set& anElems = (*aFamsIter)->GetElements(); + set::iterator anElemsIter = anElems.begin(); + for (; anElemsIter != anElems.end(); anElemsIter++) + { + anElemFamMap[*anElemsIter] = aFamId; + } +// delete (*aFamsIter); + } + + // Storing SMDS nodes to the MED file for the MED mesh + //---------------------------------------------------- + typedef map TNodeIdMap; + TNodeIdMap aNodeIdMap; + + med_int aNbElems = myMesh->NbNodes(); + MED::TIntVector anElemNums(aNbElems); + MED::TIntVector aFamilyNums(aNbElems); + MED::TFloatVector aCoordinates(aNbElems*SMDS_MESH_DIM); + SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator(); + for(med_int iNode = 0, iCoord = 0; aNodesIter->more(); iNode++, iCoord+=SMDS_MESH_DIM){ + const SMDS_MeshNode* aNode = aNodesIter->next(); + aCoordinates[iCoord] = aNode->X(); + aCoordinates[iCoord+1] = aNode->Y(); + aCoordinates[iCoord+2] = aNode->Z(); + TNodeIdMap::key_type aNodeId = aNode->GetID(); + anElemNums[iNode] = aNodeId; + aNodeIdMap[aNodeId] = iNode+1; + //cout<GetID()<<": "<X()<<", "<Y()<<", "<Z()<GetNbElem() = "<NbEdges()){ + SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator(); + med_int aNbConnectivity = MED::GetNbConn(SMDS_MED_ENTITY,MED_SEG2,SMDS_MESH_DIM); + MED::TIntVector anElemNums(aNbElems); + MED::TIntVector aFamilyNums(aNbElems); + MED::TIntVector aConnectivity(aNbElems*aNbConnectivity); + + for(med_int iElem = 0, iConn = 0; anIter->more(); iElem++, iConn+=aNbConnectivity){ + const SMDS_MeshEdge* anElem = anIter->next(); + SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator(); + for(med_int iNode = 0; iNode < aNbConnectivity && aNodesIter->more(); iNode++){ + const SMDS_MeshElement* aNode = aNodesIter->next(); + aConnectivity[iConn+iNode] = aNodeIdMap[aNode->GetID()]; + } + anElemNums[iElem] = anElem->GetID(); + + if (anElemFamMap.find(anElem) != anElemFamMap.end()) + aFamilyNums[iElem] = anElemFamMap[anElem]; + else + aFamilyNums[iElem] = myEdgesDefaultFamilyId; + } + + PCellInfo aCellInfo = TWrapper::CrCellInfo(aMeshInfo, + SMDS_MED_ENTITY, + MED_SEG2, + SMDS_MED_CONNECTIVITY, + aConnectivity, + aFamilyNums, + anElemNums); + aMed.SetCellInfo(aCellInfo); + } + + // Storing SMDS Faces + if(med_int aNbElems = myMesh->NbFaces()){ + SMDS_FaceIteratorPtr anIter = myMesh->facesIterator(); + + med_int aNbTriaConn = MED::GetNbConn(SMDS_MED_ENTITY,MED_TRIA3,SMDS_MESH_DIM); + MED::TIntVector anTriaElemNums; + anTriaElemNums.reserve(aNbElems); + MED::TIntVector aTriaFamilyNums; + aTriaFamilyNums.reserve(aNbElems); + MED::TIntVector aTriaConn; + aTriaConn.reserve(aNbElems*aNbTriaConn); + + med_int aNbQuadConn = MED::GetNbConn(SMDS_MED_ENTITY,MED_QUAD4,SMDS_MESH_DIM); + MED::TIntVector aQuadElemNums; + aQuadElemNums.reserve(aNbElems); + MED::TIntVector aQuadFamilyNums; + aQuadFamilyNums.reserve(aNbElems); + MED::TIntVector aQuadConn; + aQuadConn.reserve(aNbElems*aNbQuadConn); + + for(med_int iElem = 0; iElem < aNbElems && anIter->more(); iElem++){ + const SMDS_MeshFace* anElem = anIter->next(); + med_int aNbNodes = anElem->NbNodes(); + SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator(); + med_int aNbConnectivity; + MED::TIntVector* anElemNums; + MED::TIntVector* aFamilyNums; + MED::TIntVector* aConnectivity; + switch(aNbNodes){ + case 3: + aNbConnectivity = aNbTriaConn; + anElemNums = &anTriaElemNums; + aFamilyNums = &aTriaFamilyNums; + aConnectivity = &aTriaConn; + break; + case 4: + aNbConnectivity = aNbQuadConn; + anElemNums = &aQuadElemNums; + aFamilyNums = &aQuadFamilyNums; + aConnectivity = &aQuadConn; + break; + } + MED::TIntVector aVector(aNbNodes); + for(med_int iNode = 0; aNodesIter->more(); iNode++){ + const SMDS_MeshElement* aNode = aNodesIter->next(); + aVector[iNode] = aNode->GetID(); + } - //MESSAGE("-------- Creation de la Famille : "<< famille << "numero " << i << " --------------"); - med_int ret = - MEDfamCr(myFileId, nommaa, fam2, i, attide, attval, attdes, natt, gro, - ngro); - ASSERT(ret == 0); - delete[]attide; - delete[]attval; + med_int aSize = aConnectivity->size(); + aConnectivity->resize(aSize+aNbConnectivity); + // There is some differnce between SMDS and MED in cells mapping + switch(aNbNodes){ + case 4: + (*aConnectivity)[aSize+0] = aNodeIdMap[aVector[0]]; + (*aConnectivity)[aSize+1] = aNodeIdMap[aVector[1]]; + (*aConnectivity)[aSize+2] = aNodeIdMap[aVector[3]]; + (*aConnectivity)[aSize+3] = aNodeIdMap[aVector[2]]; + default: + for(med_int iNode = 0; iNode < aNbNodes; iNode++) + (*aConnectivity)[aSize+iNode] = aNodeIdMap[aVector[iNode]]; + } + anElemNums->push_back(anElem->GetID()); + + if (anElemFamMap.find(anElem) != anElemFamMap.end()) + aFamilyNums->push_back(anElemFamMap[anElem]); + else + aFamilyNums->push_back(myFacesDefaultFamilyId); + } + if(med_int aNbElems = anTriaElemNums.size()){ + PCellInfo aCellInfo = TWrapper::CrCellInfo(aMeshInfo, + SMDS_MED_ENTITY, + MED_TRIA3, + SMDS_MED_CONNECTIVITY, + aTriaConn, + aTriaFamilyNums, + anTriaElemNums); + MESSAGE("Add - anEntity = "< +#include +#include extern "C" { #include } +using namespace std; + +class SMESHDS_Group; +class SMESHDS_SubMesh; + class DriverMED_W_SMESHDS_Mesh:public Mesh_Writer { + public: - public:DriverMED_W_SMESHDS_Mesh(); - ~DriverMED_W_SMESHDS_Mesh(); + DriverMED_W_SMESHDS_Mesh(); + ~DriverMED_W_SMESHDS_Mesh(); - void Add(); - void Write(); - void SetMesh(SMDS_Mesh * aMesh); - void SetFile(string); + /*! sets file name; only for usage with Add(), not Write() + */ + void SetFile(string); + void AddGroupOfNodes(); + void AddGroupOfEdges(); + void AddGroupOfFaces(); + void AddGroupOfVolumes(); - void SetFileId(med_idt); - void SetMeshId(int); + /*! functions to prepare adding one mesh + */ + void SetMesh(SMDS_Mesh * aMesh); + void SetMeshId(int); + void SetMeshName(string theMeshName); + void AddGroup(SMESHDS_Group* theGroup); + void AddAllSubMeshes(); + void AddSubMesh(SMESHDS_SubMesh* theSubMesh, int theID); - void CreateFamily(char *, char *, int, med_int); + /*! add one mesh + */ + void Add(); - private: SMDS_Mesh * myMesh; - string myFile; - med_idt myFileId; - int myMeshId; + /*! functions to write via DriverMED_W_SMDS_Mesh (no groups) + */ + void SetFileId(med_idt); + void Write(); + private: + + SMDS_Mesh * myMesh; + string myFile; + med_idt myFileId; + int myMeshId; + string myMeshName; + list myGroups; + bool myAllSubMeshes; + map mySubMeshes; + bool myDoGroupOfNodes; + bool myDoGroupOfEdges; + bool myDoGroupOfFaces; + bool myDoGroupOfVolumes; }; #endif + diff --git a/src/DriverMED/MED_Test.cxx b/src/DriverMED/MED_Test.cxx new file mode 100644 index 000000000..7d6c3cd21 --- /dev/null +++ b/src/DriverMED/MED_Test.cxx @@ -0,0 +1,28 @@ +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + +#include "DriverMED_R_SMESHDS_Mesh.h" +#include "DriverMED_W_SMESHDS_Mesh.h" + +int main(int argc, char** argv) +{ + DriverMED_R_SMESHDS_Mesh aR; + DriverMED_W_SMESHDS_Mesh aW; + return 1; +} diff --git a/src/DriverMED/Makefile.in b/src/DriverMED/Makefile.in index 1a5396a8c..18d72045c 100644 --- a/src/DriverMED/Makefile.in +++ b/src/DriverMED/Makefile.in @@ -19,9 +19,12 @@ # # See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org # +# +# # File : Makefile.in # Author : Marc Tajchman (CEA) # Module : SMESH +# $Header$ top_srcdir=@top_srcdir@ top_builddir=../.. @@ -33,29 +36,28 @@ VPATH=.:@srcdir@ # header files EXPORT_HEADERS = \ - DriverMED_R_SMESHDS_Mesh.h \ - DriverMED_R_SMESHDS_Document.h \ - DriverMED_R_SMDS_Mesh.h \ - DriverMED_W_SMESHDS_Mesh.h - #DriverMED_W_SMDS_Mesh.h \ - #DriverMED_W_SMESHDS_Document.h + DriverMED_R_SMDS_Mesh.h DriverMED_R_SMESHDS_Mesh.h DriverMED_R_SMESHDS_Document.h \ + DriverMED_W_SMDS_Mesh.h DriverMED_W_SMESHDS_Mesh.h DriverMED_W_SMESHDS_Document.h \ + DriverMED_Family.h # Libraries targets LIB = libMeshDriverMED.la LIB_SRC = \ + DriverMED_R_SMDS_Mesh.cxx \ DriverMED_R_SMESHDS_Mesh.cxx \ DriverMED_R_SMESHDS_Document.cxx \ - DriverMED_R_SMDS_Mesh.cxx \ - DriverMED_W_SMESHDS_Mesh.cxx - #DriverMED_W_SMDS_Mesh.cxx \ - #DriverMED_W_SMESHDS_Document.cxx + DriverMED_W_SMDS_Mesh.cxx \ + DriverMED_W_SMESHDS_Document.cxx \ + DriverMED_W_SMESHDS_Mesh.cxx \ + DriverMED_Family.cxx + LIB_CLIENT_IDL = LIB_SERVER_IDL = # additionnal information to compil and link file -CPPFLAGS += $(OCC_INCLUDES) $(QT_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome +CPPFLAGS += $(OCC_INCLUDES) $(QT_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS) CXXFLAGS += $(OCC_CXXFLAGS) $(MED2_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome -LDFLAGS += $(MED2_LIBS) -lMeshDriver -lmed +LDFLAGS += $(MED2_LIBS) -lMeshDriver -L${KERNEL_ROOT_DIR}/lib/salome -lMEDWrapper %_moc.cxx: %.h $(MOC) $< -o $@ diff --git a/src/DriverUNV/DriverUNV_R_SMDS_Mesh.cxx b/src/DriverUNV/DriverUNV_R_SMDS_Mesh.cxx index 36bba7472..c6286a7b3 100644 --- a/src/DriverUNV/DriverUNV_R_SMDS_Mesh.cxx +++ b/src/DriverUNV/DriverUNV_R_SMDS_Mesh.cxx @@ -3,20 +3,6 @@ using namespace std; #include "utilities.h" - -extern "C" -{ - -/** - * Factory function which will be called by SMESHDriver - */ -void * SMESH_createUNVMeshReader() -{ - return new DriverUNV_R_SMDS_Mesh(); -} - -} - DriverUNV_R_SMDS_Mesh::DriverUNV_R_SMDS_Mesh() { ; diff --git a/src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx b/src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx index a841488f7..80c02b461 100644 --- a/src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx +++ b/src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx @@ -1,7 +1,13 @@ +using namespace std; #include "DriverUNV_W_SMDS_Mesh.h" + #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" + + + + #include #define sNODE_UNV_ID " 2411" @@ -13,19 +19,6 @@ #define sELT_BEAM_DESC1 "%10d %2d 1 1 7 %1d\n" #define sELT_BEAM_DESC2 " 0 1 1\n" -extern "C" -{ - -/** - * Factory function which will be called by SMESHDriver - */ -void * SMESH_createUNVMeshWriter() -{ - return new DriverUNV_W_SMDS_Mesh(); -} - -} - DriverUNV_W_SMDS_Mesh::DriverUNV_W_SMDS_Mesh() { ; @@ -96,6 +89,7 @@ void DriverUNV_W_SMDS_Mesh::Write() SCRUTE(nb_of_volumes); fprintf(stdout, "%d %d\n", nbNodes, nbCells); + fprintf(myFileId, "%d %d\n", nbNodes, nbCells); /**************************************************************************** * ECRITURE DES NOEUDS * @@ -107,7 +101,7 @@ void DriverUNV_W_SMDS_Mesh::Write() fprintf(myFileId, "%s\n", sUNV_SEPARATOR); fprintf(myFileId, "%s\n", sNODE_UNV_ID); - SMDS_Iterator * itNodes=myMesh->nodesIterator(); + SMDS_NodeIteratorPtr itNodes=myMesh->nodesIterator(); while(itNodes->more()) { const SMDS_MeshNode * node = itNodes->next(); @@ -116,7 +110,6 @@ void DriverUNV_W_SMDS_Mesh::Write() fprintf(myFileId, "%25.16E%25.16E%25.16E\n", node->X(), node->Y(), node->Z()); } - delete itNodes; fprintf(myFileId, "%s\n", sUNV_SEPARATOR); /**************************************************************************** @@ -130,11 +123,11 @@ void DriverUNV_W_SMDS_Mesh::Write() fprintf(myFileId, "%s\n", sUNV_SEPARATOR); fprintf(myFileId, "%s\n", sELT_UNV_ID); - SMDS_Iterator * itEdges=myMesh->edgesIterator(); + SMDS_EdgeIteratorPtr itEdges=myMesh->edgesIterator(); while(itEdges->more()) { const SMDS_MeshElement * elem = itEdges->next(); - SMDS_Iterator *itn=elem->nodesIterator(); + SMDS_ElemIteratorPtr itn=elem->nodesIterator(); switch (elem->NbNodes()) { @@ -155,11 +148,9 @@ void DriverUNV_W_SMDS_Mesh::Write() break; } - delete itn; } - delete itEdges; - SMDS_Iterator * itFaces=myMesh->facesIterator(); + SMDS_FaceIteratorPtr itFaces=myMesh->facesIterator(); while(itFaces->more()) { const SMDS_MeshElement * elem = itFaces->next(); @@ -190,15 +181,13 @@ void DriverUNV_W_SMDS_Mesh::Write() fprintf(myFileId, "element not registered\n"); } - SMDS_Iterator *itn=elem->nodesIterator(); + SMDS_ElemIteratorPtr itn=elem->nodesIterator(); while(itn->more()) fprintf(myFileId, "%10d", itn->next()->GetID()); - delete itn; fprintf(myFileId, "\n"); } - delete itFaces; - SMDS_Iterator * itVolumes=myMesh->volumesIterator(); + SMDS_VolumeIteratorPtr itVolumes=myMesh->volumesIterator(); while(itVolumes->more()) { const SMDS_MeshElement * elem = itVolumes->next(); @@ -222,13 +211,11 @@ void DriverUNV_W_SMDS_Mesh::Write() break; } - SMDS_Iterator *itn=elem->nodesIterator(); + SMDS_ElemIteratorPtr itn=elem->nodesIterator(); while(itn->more()) fprintf(myFileId, "%10d", itn->next()->GetID()); - delete itn; fprintf(myFileId, "\n"); } - delete itVolumes; fprintf(myFileId, "%s\n", sUNV_SEPARATOR); diff --git a/src/DriverUNV/DriverUNV_W_SMESHDS_Mesh.cxx b/src/DriverUNV/DriverUNV_W_SMESHDS_Mesh.cxx index 2923f9fa5..905eed9ca 100644 --- a/src/DriverUNV/DriverUNV_W_SMESHDS_Mesh.cxx +++ b/src/DriverUNV/DriverUNV_W_SMESHDS_Mesh.cxx @@ -112,7 +112,7 @@ void DriverUNV_W_SMESHDS_Mesh::Add() fprintf(myFileId, "%s\n", sUNV_SEPARATOR); fprintf(myFileId, "%s\n", sNODE_UNV_ID); - SMDS_Iterator * itNodes=myMesh->nodesIterator(); + SMDS_NodeIteratorPtr itNodes=myMesh->nodesIterator(); while(itNodes->more()) { const SMDS_MeshNode * node = itNodes->next(); @@ -121,7 +121,6 @@ void DriverUNV_W_SMESHDS_Mesh::Add() fprintf(myFileId, "%25.16E%25.16E%25.16E\n", node->X(), node->Y(), node->Z()); } - delete itNodes; fprintf(myFileId, "%s\n", sUNV_SEPARATOR); /**************************************************************************** @@ -135,11 +134,11 @@ void DriverUNV_W_SMESHDS_Mesh::Add() fprintf(myFileId, "%s\n", sUNV_SEPARATOR); fprintf(myFileId, "%s\n", sELT_UNV_ID); - SMDS_Iterator * itEdges=myMesh->edgesIterator(); + SMDS_EdgeIteratorPtr itEdges=myMesh->edgesIterator(); while(itEdges->more()) { const SMDS_MeshEdge * elem = itEdges->next(); - SMDS_Iterator *itn=elem->nodesIterator(); + SMDS_ElemIteratorPtr itn=elem->nodesIterator(); switch (elem->NbNodes()) { @@ -159,11 +158,9 @@ void DriverUNV_W_SMESHDS_Mesh::Add() itn->next()->GetID(), itn->next()->GetID()); break; } - delete itn; } - delete itEdges; - SMDS_Iterator * itFaces=myMesh->facesIterator(); + SMDS_FaceIteratorPtr itFaces=myMesh->facesIterator(); while(itFaces->more()) { const SMDS_MeshElement * elem = itFaces->next(); @@ -194,15 +191,13 @@ void DriverUNV_W_SMESHDS_Mesh::Add() fprintf(myFileId, "element not registered\n"); } - SMDS_Iterator *itn=elem->nodesIterator(); + SMDS_ElemIteratorPtr itn=elem->nodesIterator(); while(itn->more()) fprintf(myFileId, "%10d", itn->next()->GetID()); - delete itn; fprintf(myFileId, "\n"); } - delete itFaces; - SMDS_Iterator * itVolumes=myMesh->volumesIterator(); + SMDS_VolumeIteratorPtr itVolumes=myMesh->volumesIterator(); while(itVolumes->more()) { const SMDS_MeshElement * elem = itVolumes->next(); @@ -226,13 +221,11 @@ void DriverUNV_W_SMESHDS_Mesh::Add() break; } - SMDS_Iterator *itn=elem->nodesIterator(); + SMDS_ElemIteratorPtr itn=elem->nodesIterator(); while(itn->more()) fprintf(myFileId, "%10d", itn->next()->GetID()); - delete itn; fprintf(myFileId, "\n"); } - delete itVolumes; fprintf(myFileId, "%s\n", sUNV_SEPARATOR); fclose(myFileId); diff --git a/src/DriverUNV/Makefile.in b/src/DriverUNV/Makefile.in index f052db37e..038ab87f1 100644 --- a/src/DriverUNV/Makefile.in +++ b/src/DriverUNV/Makefile.in @@ -35,30 +35,25 @@ VPATH=.:@srcdir@ @COMMENCE@ # header files -EXPORT_HEADERS = \ - DriverUNV_R_SMDS_Mesh.h \ - DriverUNV_W_SMDS_Mesh.h - #DriverUNV_W_SMESHDS_Mesh.h \ - #DriverUNV_W_SMESHDS_Document.h \ - #DriverUNV_R_SMESHDS_Mesh.h \ - #DriverUNV_R_SMESHDS_Document.h \ +EXPORT_HEADERS= DriverUNV_R_SMDS_Mesh.h DriverUNV_R_SMESHDS_Mesh.h DriverUNV_R_SMESHDS_Document.h \ + DriverUNV_W_SMDS_Mesh.h DriverUNV_W_SMESHDS_Mesh.h DriverUNV_W_SMESHDS_Document.h # Libraries targets LIB = libMeshDriverUNV.la LIB_SRC = \ DriverUNV_R_SMDS_Mesh.cxx \ - DriverUNV_W_SMDS_Mesh.cxx - #DriverUNV_W_SMESHDS_Mesh.cxx \ - #DriverUNV_R_SMESHDS_Mesh.cxx \ - #DriverUNV_R_SMESHDS_Document.cxx \ - #DriverUNV_W_SMESHDS_Document.cxx \ + DriverUNV_R_SMESHDS_Mesh.cxx \ + DriverUNV_R_SMESHDS_Document.cxx \ + DriverUNV_W_SMESHDS_Document.cxx \ + DriverUNV_W_SMDS_Mesh.cxx \ + DriverUNV_W_SMESHDS_Mesh.cxx LIB_CLIENT_IDL = LIB_SERVER_IDL = # additionnal information to compil and link file -CPPFLAGS += $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome +CPPFLAGS += $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS) CXXFLAGS += $(OCC_CXXFLAGS) $(MED2_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome LDFLAGS += $(MED2_LIBS) -lMeshDriver diff --git a/src/DriverUNV/UNV2411_Structure.cxx b/src/DriverUNV/UNV2411_Structure.cxx new file mode 100644 index 000000000..8425f943b --- /dev/null +++ b/src/DriverUNV/UNV2411_Structure.cxx @@ -0,0 +1,123 @@ +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + +#include + +#include "UNV2411_Structure.hxx" +#include "UNV_Utilities.hxx" + +using namespace std; +using namespace UNV; +using namespace UNV2411; + +#ifdef _DEBUG_ +static int MYDEBUG = 1; +#else +static int MYDEBUG = 0; +#endif + +static string _label_dataset = "2411"; + +UNV2411::TRecord::TRecord(): + exp_coord_sys_num(0), + disp_coord_sys_num(0), + color(0) +{} + +void UNV2411::Read(std::ifstream& in_stream, TDataSet& theDataSet) +{ + if(!in_stream.good()) + EXCEPTION(runtime_error,"ERROR: Input file not good."); + + /* + * adjust the \p istream to our + * position + */ + if(!beginning_of_dataset(in_stream,_label_dataset)) + EXCEPTION(runtime_error,"ERROR: Could not find "<<_label_dataset<<" dataset!"); + + /** + * always 3 coordinates in the UNV file, no matter + * which dimensionality libMesh is in + */ + TNodeLab aLabel; + std::string num_buf; + for(; !in_stream.eof();){ + in_stream >> aLabel ; + if(aLabel == -1){ + // end of dataset is reached + break; + } + + TRecord aRec; + in_stream>>aRec.exp_coord_sys_num; + in_stream>>aRec.disp_coord_sys_num; + in_stream>>aRec.color; + + /* + * take care of the + * floating-point data + */ + for(int d = 0; d < 3; d++){ + in_stream>>num_buf; + aRec.coord[d] = D_to_e(num_buf); + } + + theDataSet.insert(TDataSet::value_type(aLabel,aRec)); + } +} + + +void UNV2411::Write(std::ofstream& out_stream, const TDataSet& theDataSet) +{ + if(!out_stream.good()) + EXCEPTION(runtime_error,"ERROR: Output file not good."); + + /* + * Write beginning of dataset + */ + out_stream<<" -1\n"; + out_stream<<" "<<_label_dataset<<"\n"; + + TDataSet::const_iterator anIter = theDataSet.begin(); + for(; anIter != theDataSet.end(); anIter++){ + const TNodeLab& aLabel = anIter->first; + const TRecord& aRec = anIter->second; + char buf[78]; + sprintf(buf, "%10d%10d%10d%10d\n", + aLabel, + aRec.exp_coord_sys_num, + aRec.disp_coord_sys_num, + aRec.color); + out_stream< +#include + +namespace UNV2411{ + + struct TRecord{ + TRecord(); + int exp_coord_sys_num; // export coordinate system number + int disp_coord_sys_num; // displacement coordinate system number + int color; // color + double coord[3]; // node coordinates in the part coordinate system + }; + + typedef int TNodeLab; // type of node label + typedef std::map TDataSet; + + void Read(std::ifstream& in_stream, TDataSet& theDataSet); + + void Write(std::ofstream& out_stream, const TDataSet& theDataSet); + +}; + + +#endif diff --git a/src/DriverUNV/UNV2412_Structure.cxx b/src/DriverUNV/UNV2412_Structure.cxx new file mode 100644 index 000000000..43699fcd8 --- /dev/null +++ b/src/DriverUNV/UNV2412_Structure.cxx @@ -0,0 +1,202 @@ +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + +#include +#include + +#include "UNV2412_Structure.hxx" +#include "UNV_Utilities.hxx" + +using namespace std; +using namespace UNV; +using namespace UNV2412; + +#ifdef _DEBUG_ +static int MYDEBUG = 1; +#else +static int MYDEBUG = 0; +#endif + +static string _label_dataset = "2412"; + +UNV2412::TRecord::TRecord(): + phys_prop_tab_num(2), + mat_prop_tab_num(1), + color(7), + beam_orientation(0), + beam_fore_end(0), + beam_aft_end(0) +{} + +void UNV2412::Read(std::ifstream& in_stream, TDataSet& theDataSet) +{ + if(!in_stream.good()) + EXCEPTION(runtime_error,"ERROR: Input file not good."); + + /* + * adjust the \p istream to our + * position + */ + if(!beginning_of_dataset(in_stream,_label_dataset)) + EXCEPTION(runtime_error,"ERROR: Could not find "<<_label_dataset<<" dataset!"); + + TElementLab aLabel; + for(; !in_stream.eof();){ + in_stream >> aLabel ; + if(aLabel == -1){ + // end of dataset is reached + break; + } + + int n_nodes; + TRecord aRec; + in_stream>>aRec.fe_descriptor_id; + in_stream>>aRec.phys_prop_tab_num; + in_stream>>aRec.mat_prop_tab_num; + in_stream>>aRec.color; + in_stream>>n_nodes; + + if(IsBeam(aRec.fe_descriptor_id)){ + in_stream>>aRec.beam_orientation; + in_stream>>aRec.beam_fore_end; + in_stream>>aRec.beam_aft_end; + } + + aRec.node_labels.resize(n_nodes); + for(int j=0; j < n_nodes; j++){ + // read node labels + in_stream>>aRec.node_labels[j]; + } + + theDataSet.insert(TDataSet::value_type(aLabel,aRec)); + } + +} + + +void UNV2412::Write(std::ofstream& out_stream, const TDataSet& theDataSet) +{ + if(!out_stream.good()) + EXCEPTION(runtime_error,"ERROR: Output file not good."); + + /* + * Write beginning of dataset + */ + out_stream<<" -1\n"; + out_stream<<" "<<_label_dataset<<"\n"; + + TDataSet::const_iterator anIter = theDataSet.begin(); + for(; anIter != theDataSet.end(); anIter++){ + const TElementLab& aLabel = anIter->first; + const TRecord& aRec = anIter->second; + out_stream< +#include +#include + + +namespace UNV2412{ + + struct TRecord{ + TRecord(); + + int fe_descriptor_id; // FE descriptor id + int phys_prop_tab_num; // physical property table number + int mat_prop_tab_num; // material property table number + int color; // color + std::vector node_labels; // node labels defining element + + //FOR BEAM ELEMENTS ONLY + int beam_orientation; // beam orientation node number + int beam_fore_end; // beam fore-end cross section number + int beam_aft_end; // beam aft-end cross section number + }; + + typedef int TElementLab; // type of element label + typedef std::map TDataSet; + + void Read(std::ifstream& in_stream, TDataSet& theDataSet); + + void Write(std::ofstream& out_stream, const TDataSet& theDataSet); + + bool IsBeam(int theFeDescriptorId); + bool IsFace(int theFeDescriptorId); + bool IsVolume(int theFeDescriptorId); + +}; + + +#endif diff --git a/src/DriverUNV/UNV_Test.cxx b/src/DriverUNV/UNV_Test.cxx new file mode 100644 index 000000000..f9d917207 --- /dev/null +++ b/src/DriverUNV/UNV_Test.cxx @@ -0,0 +1,69 @@ +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + +#include "UNV2411_Structure.hxx" +#include "UNV2412_Structure.hxx" +#include "UNV_Utilities.hxx" + +#include "DriverUNV_R_SMDS_Mesh.h" +#include "DriverUNV_W_SMDS_Mesh.h" + +using namespace std; + +#ifdef DEBUG +static int MYDEBUG = 1; +#else +static int MYDEBUG = 0; +#endif + + +void ReadMed(const char* theFileName){ + std::ifstream in_stream(theFileName); + + UNV2411::TDataSet aDataSet2411; + UNV2411::Read(in_stream,aDataSet2411); + + in_stream.seekg(0); + UNV2412::TDataSet aDataSet2412; + UNV2412::Read(in_stream,aDataSet2412); + + string aFileName(theFileName); + aFileName += "-"; + std::ofstream out_stream(aFileName.c_str()); + + UNV2411::Write(out_stream,aDataSet2411); + UNV2412::Write(out_stream,aDataSet2412); +} + + +int main(int argc, char** argv){ + DriverUNV_R_SMDS_Mesh aR; + DriverUNV_W_SMDS_Mesh aW; + try{ + if(argc > 1){ + ReadMed(argv[1]); + } + return 0; + }catch(std::exception& exc){ + cout<<"Follow exception was accured :\n"< +#include +#include +#include + + +namespace UNV{ + using namespace std; + + class PrefixPrinter{ + static int myCounter; + public: + PrefixPrinter(); + ~PrefixPrinter(); + + static string GetPrefix(); + }; + + /** + * @returns \p false when error occured, \p true otherwise. + * Adjusts the \p in_stream to the beginning of the + * dataset \p ds_name. + */ + inline bool beginning_of_dataset(std::istream& in_file, const std::string& ds_name) + { + assert (in_file.good()); + assert (!ds_name.empty()); + + std::string olds, news; + + while(true){ + in_file >> olds >> news; + /* + * a "-1" followed by a number means the beginning of a dataset + * stop combing at the end of the file + */ + while( ((olds != "-1") || (news == "-1") ) && !in_file.eof() ){ + olds = news; + in_file >> news; + } + if(in_file.eof()) + return false; + if (news == ds_name) + return true; + } + // should never end up here + return false; + } + + /** + * Method for converting exponential notation + * from "D" to "e", for example + * \p 3.141592654D+00 \p --> \p 3.141592654e+00 + * in order to make it readable for C++. + */ + inline double D_to_e(std::string& number) + { + /* find "D" in string, start looking at + * 6th element, to improve speed. + * We dont expect a "D" earlier + */ + const int position = number.find("D",6); + if(position != std::string::npos){ + number.replace(position, 1, "e"); + } + return atof (number.c_str()); + } + +}; + + +#ifndef MESSAGE + +#define MESSAGE(msg) std::cout<<__FILE__<<"["<<__LINE__<<"]::"< +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "utilities.h" + +/* + Netgen include files +*/ + +#include "nglib.h" + +//============================================================================= +/*! + * + */ +//============================================================================= + +NETGENPlugin_NETGEN_3D::NETGENPlugin_NETGEN_3D(int hypId, int studyId, + SMESH_Gen* gen) + : SMESH_3D_Algo(hypId, studyId, gen) +{ + MESSAGE("NETGENPlugin_NETGEN_3D::NETGENPlugin_NETGEN_3D"); + _name = "NETGEN_3D"; +// _shapeType = TopAbs_SOLID; + _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);// 1 bit /shape type +// MESSAGE("_shapeType octal " << oct << _shapeType); + _compatibleHypothesis.push_back("MaxElementVolume"); + + _maxElementVolume = 0.; + + _hypMaxElementVolume = NULL; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +NETGENPlugin_NETGEN_3D::~NETGENPlugin_NETGEN_3D() +{ + MESSAGE("NETGENPlugin_NETGEN_3D::~NETGENPlugin_NETGEN_3D"); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool NETGENPlugin_NETGEN_3D::CheckHypothesis + (SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus) +{ + MESSAGE("NETGENPlugin_NETGEN_3D::CheckHypothesis"); + + _hypMaxElementVolume = NULL; + + list::const_iterator itl; + const SMESHDS_Hypothesis* theHyp; + + const list& hyps = GetUsedHypothesis(aMesh, aShape); + int nbHyp = hyps.size(); + if (!nbHyp) + { + aStatus = SMESH_Hypothesis::HYP_MISSING; + return false; // can't work with no hypothesis + } + + itl = hyps.begin(); + theHyp = (*itl); // use only the first hypothesis + + string hypName = theHyp->GetName(); + int hypId = theHyp->GetID(); + SCRUTE(hypName); + + bool isOk = false; + + if (hypName == "MaxElementVolume") + { + _hypMaxElementVolume = static_cast (theHyp); + ASSERT(_hypMaxElementVolume); + _maxElementVolume = _hypMaxElementVolume->GetMaxVolume(); + isOk =true; + aStatus = SMESH_Hypothesis::HYP_OK; + } + else + aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE; + + return isOk; +} + +//============================================================================= +/*! + *Here we are going to use the NETGEN mesher + */ +//============================================================================= + +bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape) +{ + MESSAGE("NETGENPlugin_NETGEN_3D::Compute with maxElmentsize = " << _maxElementVolume); + + bool isOk = false; + SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); + SMESH_subMesh* theSubMesh = aMesh.GetSubMesh(aShape); + //const Handle(SMESHDS_SubMesh)& subMeshDS = theSubMesh->GetSubMeshDS(); + + map netgenToDS; + + MESSAGE("NETGENPlugin_NETGEN_3D::Compute Checking the mesh Faces"); + + // check if all faces were meshed by a triangle mesher (here MESFISTO_2D) + + vector meshFaces; + vector shapeFaces; + + for (TopExp_Explorer exp(aShape,TopAbs_FACE);exp.More();exp.Next()) + { + TopoDS_Shape aShapeFace = exp.Current(); + SMESH_subMesh* aSubMesh = aMesh.GetSubMeshContaining(exp.Current()); + ASSERT (aSubMesh); + int internal_size = meshFaces.size(); + int index = 0; + for (int i = 0;iGetSubShape(); + TopoDS_Shape aFace = shapeFaces[i]; + SMESH_Algo* algoFace = _gen->GetAlgo(aMesh, aShapeFace); + string algoFaceName = algoFace->GetName(); + SCRUTE(algoFaceName); + if (algoFaceName != "MEFISTO_2D") + { + SCRUTE(algoFaceName); + ASSERT(0); + return false; + } + + bool orientationMeshFace = (aFace.Orientation() == aShapeFace.Orientation()); + + const SMESHDS_SubMesh* aSubMeshDSFace = meshFaces[i]->GetSubMeshDS(); + SCRUTE(aSubMeshDSFace); + + int nbNodes = aSubMeshDSFace->NbNodes(); + NbTotOfNodesFaces += nbNodes; + int nbTria = aSubMeshDSFace->NbElements(); + NbTotOfTria += nbTria; + int index = 0; + + MESSAGE("NETGENPlugin_NETGEN_3D::Compute The mesh Face " << (i+1) << " has " << nbNodes << " face internal Nodes, " << nbTria << " triangles"); + + SCRUTE(orientationMeshFace); + + if (orientationMeshFace) + { + MESSAGE("The mesh and face have the same orientation"); + } + else + { + MESSAGE("The mesh and face have different orientations"); + } + + SMDS_NodeIteratorPtr iteratorNodes = aSubMeshDSFace->GetNodes(); + SCRUTE(nbNodes); + index = 0; + while(iteratorNodes->more()) + { + index++; + const SMDS_MeshNode * node = iteratorNodes->next(); +// int nodeId = node->GetID(); +// double nodeX = node->X(); +// double nodeY = node->Y(); +// double nodeZ = node->Z(); +// MESSAGE("NODE -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ); + } + + SCRUTE(index); + + SMDS_ElemIteratorPtr iteratorTriangle = aSubMeshDSFace->GetElements(); + + SCRUTE(nbTria); + index = 0; + int numberOfDegeneratedTriangle = 0; + while(iteratorTriangle->more()) + { + index++; + const SMDS_MeshElement * triangle = iteratorTriangle->next(); + int triangleId = triangle->GetID(); + + SMDS_ElemIteratorPtr triangleNodesIt = triangle->nodesIterator(); + + const SMDS_MeshNode * node1 = static_cast(triangleNodesIt->next()); + double node1X = node1->X(); + double node1Y = node1->Y(); + double node1Z = node1->Z(); + + const SMDS_MeshNode * node2 = static_cast(triangleNodesIt->next()); + double node2X = node2->X(); + double node2Y = node2->Y(); + double node2Z = node2->Z(); + + const SMDS_MeshNode * node3 = static_cast(triangleNodesIt->next()); + double node3X = node3->X(); + double node3Y = node3->Y(); + double node3Z = node3->Z(); + + int triangleNode1 = node1->GetID(); + int triangleNode2 = node2->GetID(); + int triangleNode3 = node3->GetID(); + + // Compute the triangle surface + + double vect1 = ((node2Y - node1Y)*(node3Z - node1Z) - (node2Z - node1Z)*(node3Y - node1Y)); + double vect2 = - ((node2X - node1X)*(node3Z - node1Z) - (node2Z - node1Z)*(node3X - node1X)); + double vect3 = ((node2X - node1X)*(node3Y - node1Y) - (node2Y - node1Y)*(node3X - node1X)); + double epsilon = 1.0e-6; + + bool triangleIsDegenerated = ((abs(vect1) ID = " << triangleId << " N1 = " << triangleNode1 << " N2 = " << triangleNode2 << " N3 = " << triangleNode3 << " is degenerated"); +// MESSAGE("NODE -> ID = " << triangleNode1 << " X = " << node1X << " Y = " << node1Y << " Z = " << node1Z); +// MESSAGE("NODE -> ID = " << triangleNode2 << " X = " << node2X << " Y = " << node2Y << " Z = " << node2Z); +// MESSAGE("NODE -> ID = " << triangleNode3 << " X = " << node3X << " Y = " << node3Y << " Z = " << node3Z); + numberOfDegeneratedTriangle++; + } + else + { +// MESSAGE("TRIANGLE -> ID = " << triangleId << " N1 = " << triangleNode1 << " N2 = " << triangleNode2 << " N3 = " << triangleNode3 << " is normal"); + } + } + + if (numberOfDegeneratedTriangle > 0) + MESSAGE("WARNING THERE IS(ARE) " << numberOfDegeneratedTriangle << " degenerated triangle on this face"); + + SCRUTE(index); + } + + + + SCRUTE(NbTotOfTria); + SCRUTE(NbTotOfNodesFaces); + + MESSAGE("NETGENPlugin_NETGEN_3D::Compute Checking the mesh Edges"); + + // check if all edges were meshed by a edge mesher (here Regular_1D) + + vector meshEdges; + for (TopExp_Explorer exp(aShape,TopAbs_EDGE);exp.More();exp.Next()) + { + SMESH_subMesh* aSubMesh = aMesh.GetSubMeshContaining(exp.Current()); + ASSERT (aSubMesh); + int internal_size = meshEdges.size(); + int index = 0; + for (int i = 0;iGetSubShape(); + SMESH_Algo* algoEdge = _gen->GetAlgo(aMesh, aShapeEdge); + string algoEdgeName = algoEdge->GetName(); + SCRUTE(algoEdgeName); + if (algoEdgeName != "Regular_1D") + { + SCRUTE(algoEdgeName); + ASSERT(0); + return false; + } + + const SMESHDS_SubMesh* aSubMeshDSEdge = meshEdges[i]->GetSubMeshDS(); + SCRUTE(aSubMeshDSEdge); + + int nbNodes = aSubMeshDSEdge->NbNodes(); + NbTotOfNodesEdges += nbNodes; + int nbSegs = aSubMeshDSEdge->NbElements(); + NbTotOfSegs += nbSegs; + + MESSAGE("NETGENPlugin_NETGEN_3D::Compute The mesh Edge " << (i+1) << " has " << nbNodes << " edge internal Nodes, " << nbSegs << " segments"); + + SMDS_NodeIteratorPtr iteratorNodes = aSubMeshDSEdge->GetNodes(); + SCRUTE(nbNodes); + int index = 0; + while(iteratorNodes->more()) + { + index++; + const SMDS_MeshNode * node = iteratorNodes->next(); +// int nodeId = node->GetID(); +// double nodeX = node->X(); +// double nodeY = node->Y(); +// double nodeZ = node->Z(); +// MESSAGE("NODE -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ); + } + + SCRUTE(index); + } + + SCRUTE(NbTotOfNodesEdges); + SCRUTE(NbTotOfSegs); + + MESSAGE("NETGENPlugin_NETGEN_3D::Compute Checking the mesh Vertices"); + + vector meshVertices; + for (TopExp_Explorer exp(aShape,TopAbs_VERTEX);exp.More();exp.Next()) + { + SMESH_subMesh* aSubMesh = aMesh.GetSubMeshContaining(exp.Current()); + ASSERT (aSubMesh); + int internal_size = meshVertices.size(); + int index = 0; + for (int i = 0;iGetSubShape(); + + const SMESHDS_SubMesh * aSubMeshDSVertex = meshVertices[i]->GetSubMeshDS(); + SCRUTE(aSubMeshDSVertex); + + int nbNodes = aSubMeshDSVertex->NbNodes(); + NbTotOfNodesVertices += nbNodes; + + MESSAGE("NETGENPlugin_NETGEN_3D::Compute The mesh Vertex " << (i+1) << " has " << nbNodes << " Nodes"); + + SMDS_NodeIteratorPtr iteratorNodes = aSubMeshDSVertex->GetNodes(); + SCRUTE(nbNodes); + int index = 0; + while(iteratorNodes->more()) + { + index++; + const SMDS_MeshNode * node = iteratorNodes->next(); +// int nodeId = node->GetID(); +// double nodeX = node->X(); +// double nodeY = node->Y(); +// double nodeZ = node->Z(); +// MESSAGE("NODE -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ); + } + + SCRUTE(index); + } + + SCRUTE(NbTotOfNodesVertices); + + MESSAGE("NETGENPlugin_NETGEN_3D::Compute --> Analysis of all shell mesh"); + + vector meshShells; + TopoDS_Shell aShell; + + for (TopExp_Explorer exp(aShape,TopAbs_SHELL);exp.More();exp.Next()) + { + SMESH_subMesh* aSubMesh = aMesh.GetSubMesh(exp.Current()); + ASSERT(aSubMesh); + SCRUTE(aSubMesh); + aShell = TopoDS::Shell(exp.Current()); + meshShells.push_back(aSubMesh); + } + + int numberOfShells = meshShells.size(); + SCRUTE(numberOfShells); + + if (numberOfShells == 1) + { + MESSAGE("NETGENPlugin_NETGEN_3D::Compute Only one shell --> generation of the mesh using directly Netgen"); + + /* + Prepare the Netgen surface mesh from the SMESHDS + */ + + MESSAGE("NETGENPlugin_NETGEN_3D::Compute Prepare the Netgen surface mesh from the SMESHDS"); + + int spaceDimension = 3; + int nbNodesByTri = 3; + int nbNodesByTetra = 4; + + int Netgen_NbOfNodes = NbTotOfNodesFaces + + NbTotOfNodesEdges + + NbTotOfNodesVertices; + int Netgen_NbOfTria = NbTotOfTria; + int Netgen_param2ndOrder = 0; + double Netgen_paramFine = 1.; + double Netgen_paramSize = _maxElementVolume; + + SCRUTE(Netgen_NbOfNodes); + SCRUTE(Netgen_NbOfTria); + + double * Netgen_Coordinates = new double [spaceDimension* + Netgen_NbOfNodes]; + int * listNodeCoresNetgenSmesh = new int [Netgen_NbOfNodes]; + int * Netgen_Connectivity = new int [nbNodesByTri*Netgen_NbOfTria]; + double * Netgen_point = new double [spaceDimension]; + int * Netgen_triangle = new int [nbNodesByTri]; + int * Netgen_tetrahedron = new int [nbNodesByTetra]; + + for (int i=0; iGetSubMeshDS(); + + SMDS_NodeIteratorPtr iteratorNodes = aSubMeshDSVertex->GetNodes(); + + while(iteratorNodes->more()) + { + const SMDS_MeshNode * node = iteratorNodes->next(); + int nodeId = node->GetID(); + double nodeX = node->X(); + double nodeY = node->Y(); + double nodeZ = node->Z(); +// MESSAGE("NODE -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ); + listNodeCoresNetgenSmesh[indexNodes] = nodeId; + int index = indexNodes*spaceDimension; + Netgen_Coordinates[index] = nodeX; + Netgen_Coordinates[index+1] = nodeY; + Netgen_Coordinates[index+2] = nodeZ; + netgenToDS[indexNodes] = node; + indexNodes++; + } + } + + for (int i=0; iGetSubMeshDS(); + + SMDS_NodeIteratorPtr iteratorNodes = aSubMeshDSEdge->GetNodes(); + + while(iteratorNodes->more()) + { + const SMDS_MeshNode * node = iteratorNodes->next(); + int nodeId = node->GetID(); + double nodeX = node->X(); + double nodeY = node->Y(); + double nodeZ = node->Z(); +// MESSAGE("NODE -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ); + listNodeCoresNetgenSmesh[indexNodes] = node->GetID(); + int index = indexNodes*spaceDimension; + Netgen_Coordinates[index] = node->X(); + Netgen_Coordinates[index+1] = node->Y(); + Netgen_Coordinates[index+2] = node->Z(); + netgenToDS[indexNodes] = node; + indexNodes++; + } + } + + for (int i=0; iGetSubMeshDS(); + + SMDS_NodeIteratorPtr iteratorNodes = aSubMeshDSFace->GetNodes(); + + while(iteratorNodes->more()) + { + const SMDS_MeshNode * node = iteratorNodes->next(); + int nodeId = node->GetID(); + double nodeX = node->X(); + double nodeY = node->Y(); + double nodeZ = node->Z(); +// MESSAGE("NODE -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ); + listNodeCoresNetgenSmesh[indexNodes] = nodeId; + int index = indexNodes*spaceDimension; + Netgen_Coordinates[index] = nodeX; + Netgen_Coordinates[index+1] = nodeY; + Netgen_Coordinates[index+2] = nodeZ; + netgenToDS[indexNodes] = node; + indexNodes++; + } + } + + SCRUTE(indexNodes); + + for (int i=0; iGetSubMeshDS(); + + TopoDS_Shape aFace = shapeFaces[i]; + + SMDS_ElemIteratorPtr iteratorTriangle = aSubMeshDSFace->GetElements(); + + TopoDS_Shape aShapeFace = meshFaces[i]->GetSubShape(); + + bool orientationMeshFace = (aFace.Orientation() == aShapeFace.Orientation()); + + SCRUTE(orientationMeshFace); + + if (orientationMeshFace) + { + MESSAGE("The mesh and face have the same orientation"); + + while(iteratorTriangle->more()) + { + const SMDS_MeshElement * triangle = iteratorTriangle->next(); + int triangleId = triangle->GetID(); + + SMDS_ElemIteratorPtr triangleNodesIt = triangle->nodesIterator(); + + int triangleNode1 = (triangleNodesIt->next())->GetID(); + int triangleNode2 = (triangleNodesIt->next())->GetID(); + int triangleNode3 = (triangleNodesIt->next())->GetID(); + +// MESSAGE("TRIANGLE -> ID = " << triangleId << " N1 = " << triangleNode1 << " N2 = " << triangleNode2 << " N3 = " << triangleNode3); + + int N1New = 0; + int N2New = 0; + int N3New = 0; + int index = indexTrias*nbNodesByTri; + + for (int j=0; jmore()) + { + const SMDS_MeshElement * triangle = iteratorTriangle->next(); + int triangleId = triangle->GetID(); + + SMDS_ElemIteratorPtr triangleNodesIt = triangle->nodesIterator(); + + int triangleNode1 = (triangleNodesIt->next())->GetID(); + int triangleNode3 = (triangleNodesIt->next())->GetID(); + int triangleNode2 = (triangleNodesIt->next())->GetID(); + +// MESSAGE("TRIANGLE -> ID = " << triangleId << " N1 = " << triangleNode1 << " N2 = " << triangleNode2 << " N3 = " << triangleNode3); + + int N1New = 0; + int N2New = 0; + int N3New = 0; + int index = indexTrias*nbNodesByTri; + + for (int j=0; j=1) && (Nij<=Netgen_NbOfNodes)); + + nodesUsed[Nij-1] = 1; + Netgen_Connectivity[i*nbNodesByTri+j] = Nij; + } + + for (int i=0; i Adding the New Nodes to SMESHDS"); + + for (int i=0; iAddNode(Netgen_CoordinatesNew[index], + Netgen_CoordinatesNew[index+1], + Netgen_CoordinatesNew[index+2]); + + meshDS->SetNodeInVolume(node, aShell); + + index = i+Netgen_NbOfNodes; + netgenToDS[index] = node; + + listNodeShellCoresNetgenSmesh[i] = node->GetID(); + } + + SCRUTE(Netgen_NbOfNodesNew); + + SCRUTE(netgenToDS.size()); + + for (int i=0; i Adding the New elements (Tetrahedrons) to the SMESHDS"); + + for (int i=0; iAddVolume(node1,node2,node3,node4); + + meshDS->SetMeshElementOnShape(elt, aShell); + } + + /* + Free the memory needed by to generate the Netgen Mesh + */ + + MESSAGE("NETGENPlugin_NETGEN_3D::Compute Free the memory needed by to generate the Netgen Mesh"); + + delete [] Netgen_Coordinates; + delete [] Netgen_Connectivity; + delete [] Netgen_CoordinatesNew; + delete [] Netgen_ConnectivityNew; + delete [] Netgen_point; + delete [] Netgen_triangle; + delete [] Netgen_tetrahedron; + + delete [] listNodeCoresNetgenSmesh; + delete [] listNodeShellCoresNetgenSmesh; + + Ng_DeleteMesh(Netgen_mesh); + Ng_Exit(); + + /* + Verification + */ + + { + MESSAGE("NETGENPlugin_NETGEN_3D::Compute Verification of the Shell mesh"); + + TopoDS_Shape aShapeShell = meshShells[0]->GetSubShape(); + SMESH_Algo* algoShell = _gen->GetAlgo(aMesh, aShapeShell); + string algoShellName = algoShell->GetName(); + SCRUTE(algoShellName); + if (algoShellName != "NETGEN_3D") + { + SCRUTE(algoShellName); + ASSERT(0); + return false; + } + + const SMESHDS_SubMesh * aSubMeshDSShell = meshShells[0]->GetSubMeshDS(); + SCRUTE(&aSubMeshDSShell); + + int nbNodes = aSubMeshDSShell->NbNodes(); + int nbTetra = aSubMeshDSShell->NbElements(); + + MESSAGE("NETGENPlugin_NETGEN_3D::Compute The mesh Shell has " << nbNodes << " shell internal Nodes, " << nbTetra << " tetrahedrons"); + + SMDS_NodeIteratorPtr iteratorNodes = aSubMeshDSShell->GetNodes(); + + SCRUTE(nbNodes); + + int index; + + index = 0; + + while(iteratorNodes->more()) + { + index++; + const SMDS_MeshNode * node = iteratorNodes->next(); + int nodeId = node->GetID(); + double nodeX = node->X(); + double nodeY = node->Y(); + double nodeZ = node->Z(); +// MESSAGE("NODE -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ); + } + + SCRUTE(index); + + SMDS_ElemIteratorPtr iteratorTetra = aSubMeshDSShell->GetElements(); + + SCRUTE(nbTetra); + + index = 0; + while(iteratorTetra->more()) + { + index++; + const SMDS_MeshElement * tetra = iteratorTetra->next(); + int tetraId = tetra->GetID(); + + SMDS_ElemIteratorPtr tetraNodesIt = tetra->nodesIterator(); + + int tetraNode1 = (tetraNodesIt->next())->GetID(); + int tetraNode2 = (tetraNodesIt->next())->GetID(); + int tetraNode3 = (tetraNodesIt->next())->GetID(); + int tetraNode4 = (tetraNodesIt->next())->GetID(); + +// MESSAGE("TETRAHEDRON -> ID = " << tetraId << " N1 = " << tetraNode1 << " N2 = " << tetraNode2 << " N3 = " << tetraNode3 << " N4 = " << tetraNode4); + + } + + SCRUTE(index); + } + } + else + { + SCRUTE(numberOfShells); + MESSAGE("NETGENPlugin_NETGEN_3D::Compute ERROR More than one shell ????? "); + return false; + } + + return true; +} + + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & NETGENPlugin_NETGEN_3D::SaveTo(ostream & save) +{ + return save; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & NETGENPlugin_NETGEN_3D::LoadFrom(istream & load) +{ + return load; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & operator << (ostream & save, NETGENPlugin_NETGEN_3D & hyp) +{ + return hyp.SaveTo( save ); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & operator >> (istream & load, NETGENPlugin_NETGEN_3D & hyp) +{ + return hyp.LoadFrom( load ); +} diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx new file mode 100644 index 000000000..b0858806d --- /dev/null +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx @@ -0,0 +1,43 @@ +//============================================================================= +// File : NETGENPlugin_NETGEN_3D.hxx +// Moved here from SMESH_NETGEN_3D.hxx +// Created : lundi 27 Janvier 2003 +// Author : Nadir BOUHAMOU (CEA) +// Project : SALOME +// Copyright : CEA 2003 +// $Header$ +//============================================================================= + +#ifndef _NETGENPlugin_NETGEN_3D_HXX_ +#define _NETGENPlugin_NETGEN_3D_HXX_ + +#include "SMESH_3D_Algo.hxx" +#include "SMESH_Mesh.hxx" +#include "StdMeshers_MaxElementVolume.hxx" +#include "Utils_SALOME_Exception.hxx" + +class NETGENPlugin_NETGEN_3D: public SMESH_3D_Algo +{ +public: + NETGENPlugin_NETGEN_3D(int hypId, int studyId, SMESH_Gen* gen); + virtual ~NETGENPlugin_NETGEN_3D(); + + virtual bool CheckHypothesis(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus); + + virtual bool Compute(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape); + + ostream & SaveTo(ostream & save); + istream & LoadFrom(istream & load); + friend ostream & operator << (ostream & save, NETGENPlugin_NETGEN_3D & hyp); + friend istream & operator >> (istream & load, NETGENPlugin_NETGEN_3D & hyp); + +protected: + double _maxElementVolume; + + const StdMeshers_MaxElementVolume* _hypMaxElementVolume; +}; + +#endif diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_i.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_i.cxx new file mode 100644 index 000000000..489d6822e --- /dev/null +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_i.cxx @@ -0,0 +1,85 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : NETGENPlugin_NETGEN_3D_i.cxx +// Moved here from SMESH_NETGEN_3D_i.cxx +// Author : Nadir Bouhamou CEA +// Module : SMESH +// $Header$ + +using namespace std; +#include "NETGENPlugin_NETGEN_3D_i.hxx" +#include "SMESH_Gen.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +//============================================================================= +/*! + * NETGENPlugin_NETGEN_3D_i::NETGENPlugin_NETGEN_3D_i + * + * Constructor + */ +//============================================================================= + +NETGENPlugin_NETGEN_3D_i::NETGENPlugin_NETGEN_3D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + SMESH_Algo_i( thePOA ), + SMESH_3D_Algo_i( thePOA ) +{ + MESSAGE( "NETGENPlugin_NETGEN_3D_i::NETGENPlugin_NETGEN_3D_i" ); + myBaseImpl = new ::NETGENPlugin_NETGEN_3D( theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); +} + +//============================================================================= +/*! + * NETGENPlugin_NETGEN_3D_i::~NETGENPlugin_NETGEN_3D_i + * + * Destructor + */ +//============================================================================= + +NETGENPlugin_NETGEN_3D_i::~NETGENPlugin_NETGEN_3D_i() +{ + MESSAGE( "NETGENPlugin_NETGEN_3D_i::~NETGENPlugin_NETGEN_3D_i" ); +} + +//============================================================================= +/*! + * NETGENPlugin_NETGEN_3D_i::GetImpl + * + * Get implementation + */ +//============================================================================= + +::NETGENPlugin_NETGEN_3D* NETGENPlugin_NETGEN_3D_i::GetImpl() +{ + MESSAGE( "NETGENPlugin_NETGEN_3D_i::GetImpl" ); + return ( ::NETGENPlugin_NETGEN_3D* )myBaseImpl; +} + diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_i.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_i.hxx new file mode 100644 index 000000000..724fafa55 --- /dev/null +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_i.hxx @@ -0,0 +1,58 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : NETGENPlugin_NETGEN_3D_i.hxx +// Moved here from SMESH_NETGEN_3D_i.hxx +// Author : Nadir Bouhamou CEA +// Module : SMESH +// $Header$ + +#ifndef _NETGENPlugin_NETGEN_3D_I_HXX_ +#define _NETGENPlugin_NETGEN_3D_I_HXX_ + +#include +#include CORBA_SERVER_HEADER(SMESH_NetgenAlgorithm) + +#include "SMESH_3D_Algo_i.hxx" +#include "NETGENPlugin_NETGEN_3D.hxx" + +// ====================================================== +// NETGEN 3d algorithm +// ====================================================== +class NETGENPlugin_NETGEN_3D_i: + public virtual POA_NETGENPlugin::NETGENPlugin_NETGEN_3D, + public virtual SMESH_3D_Algo_i +{ +public: + // Constructor + NETGENPlugin_NETGEN_3D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~NETGENPlugin_NETGEN_3D_i(); + + // Get implementation + ::NETGENPlugin_NETGEN_3D* GetImpl(); +}; + +#endif diff --git a/src/SMESH_I/SMESH_HypothesisFactory_i.hxx b/src/NETGENPlugin/NETGENPlugin_i.cxx similarity index 57% rename from src/SMESH_I/SMESH_HypothesisFactory_i.hxx rename to src/NETGENPlugin/NETGENPlugin_i.cxx index 52fafa587..7ec0e06f5 100644 --- a/src/SMESH_I/SMESH_HypothesisFactory_i.hxx +++ b/src/NETGENPlugin/NETGENPlugin_i.cxx @@ -1,4 +1,4 @@ -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// SMESH NETGENPlugin : implementaion of SMESH idl descriptions // // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -21,40 +21,40 @@ // // // -// File : SMESH_HypothesisFactory_i.hxx -// Author : Paul RASCLE, EDF +// File : NETGENPlugin.cxx +// Author : Julia DOROVSKIKH // Module : SMESH // $Header$ -#ifndef _SMESH_HYPOTHESISFACTORY_I_HXX_ -#define _SMESH_HYPOTHESISFACTORY_I_HXX_ - -#include "SMESH_Hypothesis_i.hxx" -#include -#include using namespace std; +#include "SMESH_Hypothesis_i.hxx" +#include "SMESH_Gen_i.hxx" -class GenericHypothesisCreator_i -{ -public: - virtual SMESH_Hypothesis_i* Create(const char* anHyp, - int studyId, - ::SMESH_Gen* genImpl) = 0; -}; +#include "utilities.h" -class SMESH_HypothesisFactory_i +#include "NETGENPlugin_NETGEN_3D_i.hxx" + +//============================================================================= +/*! + * + */ +//============================================================================= + +extern "C" { -public: - SMESH_HypothesisFactory_i(); - virtual ~SMESH_HypothesisFactory_i(); + GenericHypothesisCreator_i* GetHypothesisCreator (const char* aHypName) + { + MESSAGE("GetHypothesisCreator " << aHypName); + + GenericHypothesisCreator_i* aCreator = 0; - SMESH_Hypothesis_i* Create(const char* anHyp, - CORBA::Long studyId, - ::SMESH_Gen* genImpl) - throw (SALOME::SALOME_Exception); + // Hypotheses -private: - map _creatorMap; -}; + // Algorithms + if (strcmp(aHypName, "NETGEN_3D") == 0) + aCreator = new HypothesisCreator_i; + else ; -#endif + return aCreator; + } +} diff --git a/src/NETGENPlugin/NETGENPlugin_icons.po b/src/NETGENPlugin/NETGENPlugin_icons.po new file mode 100644 index 000000000..a3f6297d7 --- /dev/null +++ b/src/NETGENPlugin/NETGENPlugin_icons.po @@ -0,0 +1,20 @@ +# This is a Qt message file in .po format. Each msgid starts with +# a scope. This scope should *NOT* be translated - eg. "Foo::Bar" +# would be translated to "Pub", not "Foo::Pub". +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2002-05-28 10:57:43 AM CEST\n" +"PO-Revision-Date: YYYY-MM-DD\n" +"Last-Translator: FULLNAME \n" +"Content-Type: text/plain; charset=iso-8859-1\n" + + +#----------------------------------------------------------- +# ObjectBrowser +#----------------------------------------------------------- + +#mesh_tree_algo_netgen +msgid "ICON_SMESH_TREE_ALGO_NETGEN_3D" +msgstr "mesh_tree_algo_tetra.png" +#msgstr "mesh_tree_algo_netgen.png" diff --git a/src/OBJECT/Makefile.in b/src/OBJECT/Makefile.in index fbce0dc25..ac9be864c 100644 --- a/src/OBJECT/Makefile.in +++ b/src/OBJECT/Makefile.in @@ -27,31 +27,32 @@ top_srcdir=@top_srcdir@ top_builddir=../.. srcdir=@srcdir@ -VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl:${KERNEL_ROOT_DIR}/idl/salome:${MED_ROOT_DIR}/idl/salome +VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl @COMMENCE@ -EXPORT_HEADERS = SMESH_Actor.h \ - SMESH_Grid.h +EXPORT_HEADERS = SMESH_Actor.h SMESH_Object.h # Libraries targets LIB = libSMESHObject.la -LIB_SRC = SMESH_Actor.cxx \ - SMESH_Grid.cxx +LIB_SRC = SMESH_Object.cxx SMESH_DeviceActor.cxx SMESH_Actor.cxx + +LIB_CLIENT_IDL = SALOME_Exception.idl \ + SALOME_GenericObj.idl \ + SMESH_Mesh.idl \ + SMESH_Filter.idl \ + SMESH_Group.idl -LIB_CLIENT_IDL = # Executables targets BIN = BIN_SRC = -CPPFLAGS+=$(QT_INCLUDES) $(PYTHON_INCLUDES) $(OCC_INCLUDES) $(VTK_INCLUDES) $(OGL_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome -LDFLAGS+=$(QT_MT_LIBS) $(OCC_KERNEL_LIBS) $(VTK_LIBS) $(OGL_LIBS) $(PYTHON_LIBS) -lSalomeObject -L${KERNEL_ROOT_DIR}/lib/salome - -%_moc.cxx: %.h - $(MOC) $< -o $@ - +CPPFLAGS+=$(OCC_INCLUDES) $(VTK_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome \ + $(BOOST_CPPFLAGS) $(QT_INCLUDES) +LDFLAGS+=$(OCC_KERNEL_LIBS) $(VTK_LIBS) -L${KERNEL_ROOT_DIR}/lib/salome -lSMDS \ + -lSalomeGUI -lSalomeObject -lOpUtil @CONCLUDE@ diff --git a/src/OBJECT/SMESH_Actor.cxx b/src/OBJECT/SMESH_Actor.cxx index a48f011be..29a1f094b 100644 --- a/src/OBJECT/SMESH_Actor.cxx +++ b/src/OBJECT/SMESH_Actor.cxx @@ -26,594 +26,1262 @@ // Module : SMESH // $Header$ -using namespace std; -/*! - \class SMESH_Actor SMESH_Actor.h - \brief ... -*/ #include "SMESH_Actor.h" -#include "SMESH_Grid.h" +#include "SMESH_DeviceActor.h" +#include "SALOME_ExtractUnstructuredGrid.h" + +#include "QAD_Config.h" #include "utilities.h" +#include -// VTK Includes #include -#include -#include -#include -#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef _DEBUG_ +static int MYDEBUG = 1; +static int MYDEBUGWITHFILES = 0; +#else +static int MYDEBUG = 0; +static int MYDEBUGWITHFILES = 0; +#endif -//------------------------------------------------------------- -// Main methods -//------------------------------------------------------------- +using namespace std; -SMESH_Actor* SMESH_Actor::New() -{ - // First try to create the object from the vtkObjectFactory - vtkObject* ret = vtkObjectFactory::CreateInstance("SMESH_Actor"); - if(ret) - { - return (SMESH_Actor*)ret; - } - // If the factory was unable to create the object, then create it here. - return new SMESH_Actor; + +inline float GetFloat(const QString& theValue, float theDefault = 0){ + if(theValue.isEmpty()) return theDefault; + QString aValue = QAD_CONFIG->getSetting(theValue); + if(aValue.isEmpty()) return theDefault; + return aValue.toFloat(); } -SMESH_Actor::SMESH_Actor() -{ - this->Device = vtkActor::New(); +SMESH_Actor* SMESH_Actor::New(){ + return new SMESH_Actor(); +} - this->EdgeDevice = vtkActor::New(); - EdgeDevice->VisibilityOff(); - EdgeDevice->PickableOff(); - this->EdgeShrinkDevice = vtkActor::New(); - EdgeShrinkDevice->VisibilityOff(); - EdgeShrinkDevice->PickableOff(); +SMESH_Actor* SMESH_Actor::New(TVisualObjPtr theVisualObj, + SMESH::FilterManager_ptr theFilterMgr, + const char* theEntry, + const char* theName, + int theIsClear) +{ + SMESH_Actor* anActor = SMESH_Actor::New(); + anActor->Init(theVisualObj,theFilterMgr,theEntry,theName,theIsClear); + return anActor; +} - DataSource = NULL; - myIO = NULL; +SMESH_Actor::SMESH_Actor(){ + if(MYDEBUG) MESSAGE("SMESH_Actor"); + + myIsPointsVisible = false; + + myIsShrinkable = false; + myIsShrunk = false; + + float aPointSize = GetFloat("SMESH:SettingsNodesSize",3); + float aLineWidth = GetFloat("SMESH:SettingsWidth",1); + + vtkMatrix4x4 *aMatrix = vtkMatrix4x4::New(); + SALOME_ExtractUnstructuredGrid* aFilter = NULL; + + //Definition 2D and 3D divices of the actor + //----------------------------------------- + float anRGB[3] = {1,1,1}; + mySurfaceProp = vtkProperty::New(); + anRGB[0] = GetFloat("SMESH:SettingsFillColorRed", 0)/255.; + anRGB[1] = GetFloat("SMESH:SettingsFillColorGreen", 170)/255.; + anRGB[2] = GetFloat("SMESH:SettingsFillColorBlue", 255)/255.; + mySurfaceProp->SetColor(anRGB[0],anRGB[1],anRGB[2]); + + myBackSurfaceProp = vtkProperty::New(); + anRGB[0] = GetFloat("SMESH:SettingsBackFaceColorRed", 0)/255.; + anRGB[1] = GetFloat("SMESH:SettingsBackFaceColorGreen", 0)/255.; + anRGB[2] = GetFloat("SMESH:SettingsBackFaceColorBlue", 255)/255.; + myBackSurfaceProp->SetColor(anRGB[0],anRGB[1],anRGB[2]); + + my2DActor = SMESH_DeviceActor::New(); + my2DActor->SetUserMatrix(aMatrix); + my2DActor->SetStoreMapping(true); + my2DActor->PickableOff(); + my2DActor->SetProperty(mySurfaceProp); + my2DActor->SetBackfaceProperty(myBackSurfaceProp); + my2DActor->SetRepresentation(SMESH_DeviceActor::eSurface); + aFilter = my2DActor->GetExtractUnstructuredGrid(); + aFilter->SetModeOfChanging(SALOME_ExtractUnstructuredGrid::eAdding); + aFilter->RegisterCellsWithType(VTK_TRIANGLE); + aFilter->RegisterCellsWithType(VTK_POLYGON); + aFilter->RegisterCellsWithType(VTK_QUAD); + + my3DActor = SMESH_DeviceActor::New(); + my3DActor->SetUserMatrix(aMatrix); + my3DActor->SetStoreMapping(true); + my3DActor->PickableOff(); + my3DActor->SetProperty(mySurfaceProp); + my3DActor->SetBackfaceProperty(myBackSurfaceProp); + my3DActor->SetRepresentation(SMESH_DeviceActor::eSurface); + aFilter = my3DActor->GetExtractUnstructuredGrid(); + aFilter->SetModeOfChanging(SALOME_ExtractUnstructuredGrid::eAdding); + aFilter->RegisterCellsWithType(VTK_TETRA); + aFilter->RegisterCellsWithType(VTK_VOXEL); + aFilter->RegisterCellsWithType(VTK_HEXAHEDRON); + aFilter->RegisterCellsWithType(VTK_WEDGE); + aFilter->RegisterCellsWithType(VTK_PYRAMID); + + + //Definition 1D divice of the actor + //--------------------------------- + myEdgeProp = vtkProperty::New(); + myEdgeProp->SetAmbient(1.0); + myEdgeProp->SetDiffuse(0.0); + myEdgeProp->SetSpecular(0.0); + anRGB[0] = GetFloat("SMESH:SettingsOutlineColorRed", 0)/255.; + anRGB[1] = GetFloat("SMESH:SettingsOutlineColorGreen", 170)/255.; + anRGB[2] = GetFloat("SMESH:SettingsOutlineColorBlue", 255)/255.; + myEdgeProp->SetColor(anRGB[0],anRGB[1],anRGB[2]); + myEdgeProp->SetLineWidth(aLineWidth); + + my1DActor = SMESH_DeviceActor::New(); + my1DActor->SetUserMatrix(aMatrix); + my1DActor->SetStoreMapping(true); + my1DActor->PickableOff(); + my1DActor->SetProperty(myEdgeProp); + my1DActor->SetRepresentation(SMESH_DeviceActor::eSurface); + aFilter = my1DActor->GetExtractUnstructuredGrid(); + aFilter->SetModeOfChanging(SALOME_ExtractUnstructuredGrid::eAdding); + aFilter->RegisterCellsWithType(VTK_LINE); + + my1DProp = vtkProperty::New(); + my1DProp->DeepCopy(myEdgeProp); + static int aCotnrolLineWidth = 3; + my1DProp->SetLineWidth(aCotnrolLineWidth); + my1DProp->SetPointSize(aPointSize); + + my1DExtProp = vtkProperty::New(); + my1DExtProp->DeepCopy(myEdgeProp); + anRGB[0] = 1 - anRGB[0]; + anRGB[1] = 1 - anRGB[1]; + anRGB[2] = 1 - anRGB[2]; + my1DExtProp->SetColor(anRGB[0],anRGB[1],anRGB[2]); + my1DExtProp->SetLineWidth(aCotnrolLineWidth); + + my1DExtActor = SMESH_DeviceActor::New(); + my1DExtActor->SetUserMatrix(aMatrix); + my1DExtActor->SetStoreMapping(true); + my1DExtActor->PickableOff(); + my1DExtActor->SetVisibility(false); + my1DExtActor->SetProperty(my1DExtProp); + my1DExtActor->SetRepresentation(SMESH_DeviceActor::eInsideframe); + aFilter = my1DExtActor->GetExtractUnstructuredGrid(); + aFilter->SetModeOfChanging(SALOME_ExtractUnstructuredGrid::eAdding); + aFilter->RegisterCellsWithType(VTK_LINE); + + + //Definition 0D divice of the actor + //--------------------------------- + myNodeProp = vtkProperty::New(); + anRGB[0] = GetFloat("SMESH:SettingsNodeColorRed",255)/255.; + anRGB[1] = GetFloat("SMESH:SettingsNodeColorGreen",0)/255.; + anRGB[2] = GetFloat("SMESH:SettingsNodeColorBlue",0)/255.; + myNodeProp->SetColor(anRGB[0],anRGB[1],anRGB[2]); + myNodeProp->SetPointSize(aPointSize); + + myNodeActor = SMESH_DeviceActor::New(); + myNodeActor->SetUserMatrix(aMatrix); + myNodeActor->SetStoreMapping(true); + myNodeActor->PickableOff(); + myNodeActor->SetVisibility(false); + myNodeActor->SetProperty(myNodeProp); + myNodeActor->SetRepresentation(SMESH_DeviceActor::ePoint); + aFilter = myNodeActor->GetExtractUnstructuredGrid(); + aFilter->SetModeOfExtraction(SALOME_ExtractUnstructuredGrid::ePoints); + + + //Definition of Pickable and Highlitable engines + //---------------------------------------------- + + myBaseActor = SMESH_DeviceActor::New(); + myBaseActor->SetUserMatrix(aMatrix); + myBaseActor->SetStoreMapping(true); + myBaseActor->GetProperty()->SetOpacity(0.0); + + myPickableActor = myBaseActor; + + myHighlightProp = vtkProperty::New(); + myHighlightProp->SetAmbient(1.0); + myHighlightProp->SetDiffuse(0.0); + myHighlightProp->SetSpecular(0.0); + anRGB[0] = GetFloat("SMESH:SettingsSelectColorRed", 255)/255.; // 1; + anRGB[1] = GetFloat("SMESH:SettingsSelectColorGreen", 255)/255.; // 1; + anRGB[2] = GetFloat("SMESH:SettingsSelectColorBlue", 255)/255.; // 1; + myHighlightProp->SetColor(anRGB[0],anRGB[1],anRGB[2]); + myHighlightProp->SetPointSize(aPointSize); + myHighlightProp->SetRepresentation(1); + + myPreselectProp = vtkProperty::New(); + myPreselectProp->SetAmbient(1.0); + myPreselectProp->SetDiffuse(0.0); + myPreselectProp->SetSpecular(0.0); + anRGB[0] = GetFloat("SMESH:SettingsPreSelectColorRed", 0)/255.; // 0; + anRGB[1] = GetFloat("SMESH:SettingsPreSelectColorGreen", 255)/255.; // 1; + anRGB[2] = GetFloat("SMESH:SettingsPreSelectColorBlue", 255)/255.; // 1; + myPreselectProp->SetColor(anRGB[0],anRGB[1],anRGB[2]); + myPreselectProp->SetPointSize(aPointSize); + myPreselectProp->SetRepresentation(1); + + myHighlitableActor = SMESH_DeviceActor::New(); + myHighlitableActor->SetUserMatrix(aMatrix); + myHighlitableActor->SetStoreMapping(false); + myHighlitableActor->PickableOff(); + myHighlitableActor->SetRepresentation(SMESH_DeviceActor::eWireframe); + + + SetShrinkFactor(GetFloat("SMESH:SettingsShrinkCoeff", 75)/100.); + myName = ""; + myIO = NULL; myDisplayMode = 0; ishighlighted = false; ispreselected = false; - edgeColor.r = 0.; - edgeColor.g = 0.; - edgeColor.b = 0.; - - edgeHighlightColor.r = 1.; - edgeHighlightColor.g = 1.; - edgeHighlightColor.b = 1.; + myColorMode = eNone; + my1DColorMode = e1DNone; + myControlActor = my2DActor; - edgePreselectedColor.r = 0.; - edgePreselectedColor.g = 1.; - edgePreselectedColor.b = 1.; + //Definition of myScalarBarActor + //------------------------------ + myLookupTable = vtkLookupTable::New(); + //Fix for Bug PAL5195 - SMESH764: + //Controls - Aspect Ratio: incorrect colors of the best and worst values + myLookupTable->SetHueRange(0.667,0.0); - actorColor.r = 1.; - actorColor.g = 1.; - actorColor.b = 0.; + myScalarBarActor = vtkScalarBarActor::New(); + myScalarBarActor->SetVisibility(false); + myScalarBarActor->SetLookupTable(myLookupTable); - actorHighlightColor.r = 1.; - actorHighlightColor.g = 1.; - actorHighlightColor.b = 1.; + vtkTextProperty* aScalarBarTitleProp = vtkTextProperty::New(); - actorPreselectedColor.r = 0.; - actorPreselectedColor.g = 1.; - actorPreselectedColor.b = 1.; + if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarTitleColor" ) ) { + QStringList aTColor = QStringList::split( ":", QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleColor" ), false ); + aScalarBarTitleProp->SetColor( ( aTColor.count() > 0 ? aTColor[0].toInt()/255. : 1.0 ), + ( aTColor.count() > 1 ? aTColor[1].toInt()/255. : 1.0 ), + ( aTColor.count() > 2 ? aTColor[2].toInt()/255. : 1.0 ) ); + } + else + aScalarBarTitleProp->SetColor( 1.0, 1.0, 1.0 ); + + aScalarBarTitleProp->SetFontFamilyToArial(); + if( QAD_CONFIG->hasSetting( "SMESH:ScalarBarTitleFont" ) ){ + if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleFont" ) == "Arial" ) + aScalarBarTitleProp->SetFontFamilyToArial(); + else if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleFont" ) == "Courier" ) + aScalarBarTitleProp->SetFontFamilyToCourier(); + else if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleFont" ) == "Times" ) + aScalarBarTitleProp->SetFontFamilyToTimes(); + } - actorNodeColor.r = 1.; - actorNodeColor.g = 1.; - actorNodeColor.b = 0.; + if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleBold" ) == "true" ) + aScalarBarTitleProp->BoldOn(); + else + aScalarBarTitleProp->BoldOff(); - actorNodeSize = 2 ; - -} + if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleItalic" ) == "true" ) + aScalarBarTitleProp->ItalicOn(); + else + aScalarBarTitleProp->ItalicOff(); -SMESH_Actor::~SMESH_Actor() -{ - this->EdgeDevice->Delete(); - this->EdgeShrinkDevice->Delete(); -} + if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleShadow" ) == "true" ) + aScalarBarTitleProp->ShadowOn(); + else + aScalarBarTitleProp->ShadowOff(); -void SMESH_Actor::setReader(vtkUnstructuredGridReader* r) { - myReader=r; -} + myScalarBarActor->SetTitleTextProperty( aScalarBarTitleProp ); + aScalarBarTitleProp->Delete(); + + vtkTextProperty* aScalarBarLabelProp = vtkTextProperty::New(); + + if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarLabelColor" ) ) { + QStringList aTColor = QStringList::split( ":", QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelColor" ), false ); + aScalarBarLabelProp->SetColor( ( aTColor.count() > 0 ? aTColor[0].toInt()/255. : 1.0 ), + ( aTColor.count() > 1 ? aTColor[1].toInt()/255. : 1.0 ), + ( aTColor.count() > 2 ? aTColor[2].toInt()/255. : 1.0 ) ); + } + else + aScalarBarLabelProp->SetColor( 1.0, 1.0, 1.0 ); + + aScalarBarLabelProp->SetFontFamilyToArial(); + if( QAD_CONFIG->hasSetting( "SMESH:ScalarBarLabelFont" ) ){ + if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelFont" ) == "Arial" ) + aScalarBarLabelProp->SetFontFamilyToArial(); + else if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelFont" ) == "Courier" ) + aScalarBarLabelProp->SetFontFamilyToCourier(); + else if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelFont" ) == "Times" ) + aScalarBarLabelProp->SetFontFamilyToTimes(); + } + + if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelBold" ) == "true" ) + aScalarBarLabelProp->BoldOn(); + else + aScalarBarLabelProp->BoldOff(); + + if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelItalic" ) == "true" ) + aScalarBarLabelProp->ItalicOn(); + else + aScalarBarLabelProp->ItalicOff(); + + if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelShadow" ) == "true" ) + aScalarBarLabelProp->ShadowOn(); + else + aScalarBarLabelProp->ShadowOff(); + + myScalarBarActor->SetLabelTextProperty( aScalarBarLabelProp ); + aScalarBarLabelProp->Delete(); + + if ( QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" ) + myScalarBarActor->SetOrientationToHorizontal(); + else + myScalarBarActor->SetOrientationToVertical(); + + float aXVal = QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" ? 0.20 : 0.01; + if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarXPosition" ) ) + aXVal = QAD_CONFIG->getSetting( "SMESH:ScalarBarXPosition" ).toFloat(); + float aYVal = QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" ? 0.01 : 0.1; + if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarYPosition" ) ) + aYVal = QAD_CONFIG->getSetting( "SMESH:ScalarBarYPosition" ).toFloat(); + myScalarBarActor->SetPosition( aXVal, aYVal ); + + float aWVal = QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" ? 0.60 : 0.10; + if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarWidth" ) ) + aWVal = QAD_CONFIG->getSetting( "SMESH:ScalarBarWidth" ).toFloat(); + myScalarBarActor->SetWidth( aWVal ); + + float aHVal = QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" ? 0.12 : 0.80; + if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarHeight" ) ) + aHVal = QAD_CONFIG->getSetting( "SMESH:ScalarBarHeight" ).toFloat(); + myScalarBarActor->SetHeight( aHVal ); + + int anIntVal = 5; + if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarNbOfLabels" ) ) + anIntVal = QAD_CONFIG->getSetting("SMESH:ScalarBarNbOfLabels").toInt(); + myScalarBarActor->SetNumberOfLabels(anIntVal == 0? 5: anIntVal); + + anIntVal = 64; + if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarNbOfColors" ) ) + anIntVal = QAD_CONFIG->getSetting("SMESH:ScalarBarNbOfColors").toInt(); + myScalarBarActor->SetMaximumNumberOfColors(anIntVal == 0? 64: anIntVal); + + + //Definition of points numbering pipeline + //--------------------------------------- + myPointsNumDataSet = vtkUnstructuredGrid::New(); + + myPtsMaskPoints = vtkMaskPoints::New(); + myPtsMaskPoints->SetInput(myPointsNumDataSet); + myPtsMaskPoints->SetOnRatio(1); + + myPtsSelectVisiblePoints = vtkSelectVisiblePoints::New(); + myPtsSelectVisiblePoints->SetInput(myPtsMaskPoints->GetOutput()); + myPtsSelectVisiblePoints->SelectInvisibleOff(); + myPtsSelectVisiblePoints->SetTolerance(0.1); + + myPtsLabeledDataMapper = vtkLabeledDataMapper::New(); + myPtsLabeledDataMapper->SetInput(myPtsSelectVisiblePoints->GetOutput()); + myPtsLabeledDataMapper->SetLabelFormat("%g"); + myPtsLabeledDataMapper->SetLabelModeToLabelScalars(); + + vtkTextProperty* aPtsTextProp = vtkTextProperty::New(); + aPtsTextProp->SetFontFamilyToTimes(); + static int aPointsFontSize = 10; + aPtsTextProp->SetFontSize(aPointsFontSize); + aPtsTextProp->SetBold(1); + aPtsTextProp->SetItalic(0); + aPtsTextProp->SetShadow(0); + myPtsLabeledDataMapper->SetLabelTextProperty(aPtsTextProp); + aPtsTextProp->Delete(); + + myIsPointsLabeled = false; + + myPointLabels = vtkActor2D::New(); + myPointLabels->SetMapper(myPtsLabeledDataMapper); + myPointLabels->GetProperty()->SetColor(1,1,1); + myPointLabels->SetVisibility(myIsPointsLabeled); + + + //Definition of cells numbering pipeline + //--------------------------------------- + myCellsNumDataSet = vtkUnstructuredGrid::New(); + + myCellCenters = vtkCellCenters::New(); + myCellCenters->SetInput(myCellsNumDataSet); -vtkUnstructuredGridReader* SMESH_Actor::getReader() { - return (myReader); + myClsMaskPoints = vtkMaskPoints::New(); + myClsMaskPoints->SetInput(myCellCenters->GetOutput()); + myClsMaskPoints->SetOnRatio(1); + + myClsSelectVisiblePoints = vtkSelectVisiblePoints::New(); + myClsSelectVisiblePoints->SetInput(myClsMaskPoints->GetOutput()); + myClsSelectVisiblePoints->SelectInvisibleOff(); + myClsSelectVisiblePoints->SetTolerance(0.1); + + myClsLabeledDataMapper = vtkLabeledDataMapper::New(); + myClsLabeledDataMapper->SetInput(myClsSelectVisiblePoints->GetOutput()); + myClsLabeledDataMapper->SetLabelFormat("%g"); + myClsLabeledDataMapper->SetLabelModeToLabelScalars(); + + vtkTextProperty* aClsTextProp = vtkTextProperty::New(); + aClsTextProp->SetFontFamilyToTimes(); + static int aCellsFontSize = 12; + aClsTextProp->SetFontSize(aCellsFontSize); + aClsTextProp->SetBold(1); + aClsTextProp->SetItalic(0); + aClsTextProp->SetShadow(0); + myClsLabeledDataMapper->SetLabelTextProperty(aClsTextProp); + aClsTextProp->Delete(); + + myIsCellsLabeled = false; + + myCellsLabels = vtkActor2D::New(); + myCellsLabels->SetMapper(myClsLabeledDataMapper); + myCellsLabels->GetProperty()->SetColor(0,1,0); + myCellsLabels->SetVisibility(myIsCellsLabeled); } -vtkMapper* SMESH_Actor::getMapper() { - return (this->Mapper); + +SMESH_Actor::~SMESH_Actor(){ + if(MYDEBUG) MESSAGE("~SMESH_Actor"); + + myScalarBarActor->Delete(); + myLookupTable->Delete(); + + mySurfaceProp->Delete(); + myBackSurfaceProp->Delete(); + + myEdgeProp->Delete(); + myHighlightProp->Delete(); + myPreselectProp->Delete(); + + myNodeProp->Delete(); + + my1DProp->Delete(); + my1DActor->Delete(); + + my1DExtProp->Delete(); + my1DExtActor->Delete(); + + my2DActor->Delete(); + my3DActor->Delete(); + + myNodeActor->Delete(); + myBaseActor->Delete(); + myHighlitableActor->Delete(); + + + //Deleting of pints numbering pipeline + //--------------------------------------- + myPointsNumDataSet->Delete(); + + myPtsLabeledDataMapper->RemoveAllInputs(); + myPtsLabeledDataMapper->Delete(); + + myPtsSelectVisiblePoints->UnRegisterAllOutputs(); + myPtsSelectVisiblePoints->Delete(); + + myPtsMaskPoints->UnRegisterAllOutputs(); + myPtsMaskPoints->Delete(); + + myPointLabels->Delete(); + + + //Deleting of cells numbering pipeline + //--------------------------------------- + myCellsNumDataSet->Delete(); + + myClsLabeledDataMapper->RemoveAllInputs(); + myClsLabeledDataMapper->Delete(); + + myClsSelectVisiblePoints->UnRegisterAllOutputs(); + myClsSelectVisiblePoints->Delete(); + + myClsMaskPoints->UnRegisterAllOutputs(); + myClsMaskPoints->Delete(); + + myCellCenters->UnRegisterAllOutputs(); + myCellCenters->Delete(); + + myCellsLabels->Delete(); } -void SMESH_Actor::ShallowCopy(vtkProp *prop) + +void SMESH_Actor::SetPointsLabeled( bool theIsPointsLabeled ) { - SMESH_Actor *f = SMESH_Actor::SafeDownCast(prop); - if ( f != NULL ) + myIsPointsLabeled = theIsPointsLabeled; + + if ( myIsPointsLabeled ) + { + myPointsNumDataSet->ShallowCopy( GetUnstructuredGrid() ); + vtkDataSet *aDataSet = myPointsNumDataSet; + + int aNbElem = aDataSet->GetNumberOfPoints(); + + vtkIntArray *anArray = vtkIntArray::New(); + anArray->SetNumberOfValues( aNbElem ); + + for ( int anId = 0; anId < aNbElem; anId++ ) { - this->setName( f->getName() ); - if ( f->hasIO() ) - this->setIO( f->getIO() ); - this->setDisplayMode( f->getDisplayMode() ); - - // Copy devices - vtkActor* tempDev = vtkActor::New(); - tempDev->ShallowCopy(f->Device); - vtkProperty* prp = vtkProperty::New(); - prp->DeepCopy(f->Device->GetProperty()); - tempDev->SetProperty(prp); - prp = vtkProperty::New(); - prp->DeepCopy(f->Device->GetBackfaceProperty()); - tempDev->SetBackfaceProperty(prp); - this->Device = tempDev; - - tempDev = vtkActor::New(); - tempDev->ShallowCopy(f->EdgeDevice); - prp = vtkProperty::New(); - prp->DeepCopy(f->EdgeDevice->GetProperty()); - tempDev->SetProperty(prp); - prp = vtkProperty::New(); - prp->DeepCopy(f->EdgeDevice->GetBackfaceProperty()); - tempDev->SetBackfaceProperty(prp); - this->EdgeDevice = tempDev; - - tempDev = vtkActor::New(); - tempDev->ShallowCopy(f->EdgeShrinkDevice); - prp = vtkProperty::New(); - prp->DeepCopy(f->EdgeShrinkDevice->GetProperty()); - tempDev->SetProperty(prp); - prp = vtkProperty::New(); - prp->DeepCopy(f->EdgeShrinkDevice->GetBackfaceProperty()); - tempDev->SetBackfaceProperty(prp); - this->EdgeShrinkDevice = tempDev; - - // Copy data source - this->DataSource = f->DataSource; - - this->myReader = f->myReader; + int aSMDSId = myVisualObj->GetNodeObjId( anId ); + anArray->SetValue( anId, aSMDSId ); } - - // Now do superclass - this->SALOME_Actor::ShallowCopy(prop); - - // Here we need to modify default ShallowCopy() results - // Create copies of properties - if ( f != NULL ) { - vtkProperty* prp = vtkProperty::New(); - prp->DeepCopy(f->GetProperty()); - this->SetProperty(prp); - - prp = vtkProperty::New(); - prp->DeepCopy(f->GetBackfaceProperty()); - this->SetBackfaceProperty(prp); - - // Copy the mapper - vtkDataSetMapper* mpr = vtkDataSetMapper::New(); - mpr->ShallowCopy(f->GetMapper()); - mpr->SetInput(f->DataSource); - this->SetMapper(mpr); + + aDataSet->GetPointData()->SetScalars( anArray ); + anArray->Delete(); + myPtsMaskPoints->SetInput( aDataSet ); + myPointLabels->SetVisibility( GetVisibility() ); } -} - -void SMESH_Actor::Render(vtkRenderer *ren, vtkMapper *Mapper ) -{ - if (this->Mapper == NULL) { - MESSAGE ("No mapper for actor.") - return; + else + { + myPointLabels->SetVisibility( false ); } + + SetRepresentation( GetRepresentation() ); +} - if ( myDisplayMode == 1 ) { - EdgeDevice->VisibilityOn(); - EdgeShrinkDevice->VisibilityOff(); - } else if ( myDisplayMode == 2 ) { - EdgeShrinkDevice->VisibilityOn(); - EdgeDevice->VisibilityOff(); - } else { - EdgeShrinkDevice->VisibilityOff(); - EdgeDevice->VisibilityOff(); - } - - - vtkMapper *bestMapper; - bestMapper = this->Mapper; - - /* render the property */ - if (!this->Property) { - // force creation of a property - this->GetProperty(); - } - if ( ishighlighted ) { - if ( myDisplayMode == 1 ) { - EdgeDevice->GetProperty()->SetColor(edgeHighlightColor.r,edgeHighlightColor.g,edgeHighlightColor.b); - this->GetProperty()->SetColor(actorColor.r,actorColor.g,actorColor.b); - } else if ( myDisplayMode == 2 ) { - EdgeShrinkDevice->GetProperty()->SetColor(edgeHighlightColor.r,edgeHighlightColor.g,edgeHighlightColor.b); - } else { - this->GetProperty()->SetColor(actorHighlightColor.r,actorHighlightColor.g,actorHighlightColor.b); - } - } else if (! ispreselected ) { - if ( myDisplayMode == 1 ) { - EdgeDevice->GetProperty()->SetColor(edgeColor.r,edgeColor.g,edgeColor.b); - this->GetProperty()->SetColor(actorColor.r,actorColor.g,actorColor.b); +void SMESH_Actor::SetCellsLabeled(bool theIsCellsLabeled){ + myIsCellsLabeled = theIsCellsLabeled; + if(myIsCellsLabeled){ + myCellsNumDataSet->ShallowCopy(GetUnstructuredGrid()); + vtkDataSet *aDataSet = myCellsNumDataSet; + int aNbElem = aDataSet->GetNumberOfCells(); + vtkIntArray *anArray = vtkIntArray::New(); + anArray->SetNumberOfValues(aNbElem); + for(int anId = 0; anId < aNbElem; anId++){ + int aSMDSId = myVisualObj->GetElemObjId(anId); + anArray->SetValue(anId,aSMDSId); } - else if ( myDisplayMode == 2 ) - EdgeShrinkDevice->GetProperty()->SetColor(edgeColor.r,edgeColor.g,edgeColor.b); - else - this->GetProperty()->SetColor(actorColor.r,actorColor.g,actorColor.b); - } - else { - if ( myDisplayMode == 1 ) - EdgeDevice->GetProperty()->SetColor(edgePreselectedColor.r,edgePreselectedColor.g,edgePreselectedColor.b); - else if ( myDisplayMode == 2 ) - EdgeShrinkDevice->GetProperty()->SetColor(edgePreselectedColor.r,edgePreselectedColor.g,edgePreselectedColor.b); - else - this->GetProperty()->SetColor(actorPreselectedColor.r,actorPreselectedColor.g,actorPreselectedColor.b); + aDataSet->GetCellData()->SetScalars(anArray); + myCellCenters->SetInput(aDataSet); + myCellsLabels->SetVisibility(GetVisibility()); + }else{ + myCellsLabels->SetVisibility(false); } +} - this->Property->Render(this, ren); - if (this->BackfaceProperty) { - this->BackfaceProperty->BackfaceRender(this, ren); - this->Device->SetBackfaceProperty(this->BackfaceProperty); - } - this->Device->SetProperty(this->Property); - - /* render the texture */ - if (this->Texture) { - this->Texture->Render(ren); + +void SMESH_Actor::SetControlMode(eControl theMode){ + myColorMode = eNone; + my1DColorMode = e1DNone; + + my1DActor->GetMapper()->SetScalarVisibility(false); + my2DActor->GetMapper()->SetScalarVisibility(false); + my3DActor->GetMapper()->SetScalarVisibility(false); + myScalarBarActor->SetVisibility(false); + + bool anIsScalarVisible = theMode > eNone; + + if(anIsScalarVisible){ + SMESH::NumericalFunctor_var aFunctor; + SMESH::Predicate_var aPredicate; + + switch(theMode){ + case eLengthEdges: + aFunctor = myFilterMgr->CreateLength(); + myControlActor = my1DActor; + break; + case eFreeBorders: + aPredicate = myFilterMgr->CreateFreeBorders(); + myControlActor = my1DActor; + break; + case eMultiConnection: + aFunctor = myFilterMgr->CreateMultiConnection(); + myControlActor = my1DActor; + break; + case eArea: + aFunctor = myFilterMgr->CreateArea(); + myControlActor = my2DActor; + break; + case eTaper: + aFunctor = myFilterMgr->CreateTaper(); + myControlActor = my2DActor; + break; + case eAspectRatio: + aFunctor = myFilterMgr->CreateAspectRatio(); + myControlActor = my2DActor; + break; + case eMinimumAngle: + aFunctor = myFilterMgr->CreateMinimumAngle(); + myControlActor = my2DActor; + break; + case eWarping: + aFunctor = myFilterMgr->CreateWarping(); + myControlActor = my2DActor; + break; + case eSkew: + aFunctor = myFilterMgr->CreateSkew(); + myControlActor = my2DActor; + break; + default: + return; + } + + vtkUnstructuredGrid* aGrid = myControlActor->GetUnstructuredGrid(); + vtkIdType aNbCells = aGrid->GetNumberOfCells(); + if(aNbCells){ + if(theMode == eFreeBorders){ + if(!aPredicate->_is_nil()){ + myVisualObj->UpdateFunctor(aPredicate); + SALOME_ExtractUnstructuredGrid* aFilter = + my1DExtActor->GetExtractUnstructuredGrid(); + aFilter->SetModeOfChanging(SALOME_ExtractUnstructuredGrid::eAdding); + aFilter->ClearRegisteredCells(); + for( vtkIdType i = 0; i < aNbCells; i++ ){ + vtkIdType anObjId = myControlActor->GetElemObjId( i ); + CORBA::Boolean aValue = aPredicate->IsSatisfy(anObjId); + if(aValue) + aFilter->RegisterCell(i); + } + if(!aFilter->IsCellsRegistered()) + aFilter->RegisterCell(-1); + aPredicate->Destroy(); + } + myColorMode = theMode; + my1DColorMode = e1DHighlited; + }else{ + myColorMode = theMode; + if(myControlActor == my1DActor) + my1DColorMode = e1DColored; + + vtkUnstructuredGrid* aDataSet = vtkUnstructuredGrid::New(); + aDataSet->ShallowCopy(aGrid); + myScalarBarActor->SetVisibility(true); + myControlActor->GetMapper()->SetScalarVisibility(true); + + vtkDoubleArray *aScalars = vtkDoubleArray::New(); + aScalars->SetNumberOfComponents( 1 ); + aScalars->SetNumberOfTuples(aNbCells); + + if(!aFunctor->_is_nil()){ + myVisualObj->UpdateFunctor(aFunctor); + for( vtkIdType i = 0; i < aNbCells; i++ ){ + vtkIdType anObjId = myControlActor->GetElemObjId( i ); + CORBA::Double aValue = aFunctor->GetValue(anObjId); + aScalars->SetValue( i, aValue ); + } + aFunctor->Destroy(); + }else if(!aPredicate->_is_nil()){ + myVisualObj->UpdateFunctor(aPredicate); + for( vtkIdType i = 0; i < aNbCells; i++ ){ + vtkIdType anObjId = myControlActor->GetElemObjId( i ); + CORBA::Boolean aValue = aPredicate->IsSatisfy(anObjId); + aScalars->SetValue( i, aValue ); + } + aPredicate->Destroy(); + } + aDataSet->GetCellData()->SetScalars(aScalars); + aScalars->Delete(); + + float aRange[2]; + aScalars->GetRange(aRange); + myLookupTable->SetRange(aRange); + myLookupTable->Build(); + + myControlActor->GetMergeFilter()->SetScalars(aDataSet); + aDataSet->Delete(); + if(MYDEBUGWITHFILES) + WriteUnstructuredGrid(aDataSet,"/tmp/SetControlMode.vtk"); + } + } } + SetRepresentation(GetRepresentation()); - - // Store information on time it takes to render. - // We might want to estimate time from the number of polygons in mapper. - this->Device->Render(ren,bestMapper); - this->EstimatedRenderTime = bestMapper->GetTimeToDraw(); + Modified(); } -int SMESH_Actor::RenderOpaqueGeometry(vtkViewport *vp) + +void SMESH_Actor::AddToRender(vtkRenderer* theRenderer){ + SALOME_Actor::AddToRender(theRenderer); + + theRenderer->AddActor(myNodeActor); + theRenderer->AddActor(myBaseActor); + + theRenderer->AddActor(my3DActor); + theRenderer->AddActor(my2DActor); + + theRenderer->AddActor(my1DActor); + theRenderer->AddActor(my1DExtActor); + + theRenderer->AddActor(myHighlitableActor); + + theRenderer->AddActor2D(myScalarBarActor); + + myPtsSelectVisiblePoints->SetRenderer(theRenderer); + myClsSelectVisiblePoints->SetRenderer(theRenderer); + + theRenderer->AddActor2D(myPointLabels); + theRenderer->AddActor2D(myCellsLabels); +} + +void SMESH_Actor::RemoveFromRender(vtkRenderer* theRenderer){ + SALOME_Actor::RemoveFromRender(theRenderer); + + theRenderer->RemoveActor(myNodeActor); + theRenderer->RemoveActor(myBaseActor); + theRenderer->RemoveActor(myHighlitableActor); + + theRenderer->RemoveActor(my1DActor); + theRenderer->RemoveActor(my1DExtActor); + + theRenderer->RemoveActor(my2DActor); + theRenderer->RemoveActor(my3DActor); + + theRenderer->RemoveActor(myScalarBarActor); + theRenderer->RemoveActor(myPointLabels); + theRenderer->RemoveActor(myCellsLabels); +} + + +void SMESH_Actor::Init(TVisualObjPtr theVisualObj, + SMESH::FilterManager_ptr theFilterMgr, + const char* theEntry, + const char* theName, + int theIsClear) { - int renderedSomething = 0; - vtkRenderer *ren = (vtkRenderer *)vp; - - if ( ! this->Mapper ) { - return 0; - } - - // make sure we have a property - if (!this->Property) { - // force creation of a property - this->GetProperty(); - } + Handle(SALOME_InteractiveObject) anIO = + new SALOME_InteractiveObject(strdup(theEntry),strdup("MESH"),strdup(theName)); + setIO(anIO); + setName(strdup(theName)); + + myVisualObj = theVisualObj; + myNodeActor->myVisualObj = myVisualObj; + myBaseActor->myVisualObj = myVisualObj; + myHighlitableActor->myVisualObj = myVisualObj; + + my1DActor->myVisualObj = myVisualObj; + my1DExtActor->myVisualObj = myVisualObj; + + my2DActor->myVisualObj = myVisualObj; + my3DActor->myVisualObj = myVisualObj; + + myVisualObj->Update(theIsClear); + SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid()); - if ( ishighlighted ) { - if ( myDisplayMode == 1 ) { - EdgeDevice->GetProperty()->SetColor(edgeHighlightColor.r,edgeHighlightColor.g,edgeHighlightColor.b); - } else if ( myDisplayMode == 2 ) { - EdgeShrinkDevice->GetProperty()->SetColor(edgeHighlightColor.r,edgeHighlightColor.g,edgeHighlightColor.b); - } else { - this->GetProperty()->SetColor(actorHighlightColor.r,actorHighlightColor.g,actorHighlightColor.b); - } - } else if (! ispreselected ) { - if ( myDisplayMode == 1 ) - EdgeDevice->GetProperty()->SetColor(edgeColor.r,edgeColor.g,edgeColor.b); - else if ( myDisplayMode == 2 ) - EdgeShrinkDevice->GetProperty()->SetColor(edgeColor.r,edgeColor.g,edgeColor.b); - else - this->GetProperty()->SetColor(actorColor.r,actorColor.g,actorColor.b); + myFilterMgr = SMESH::FilterManager::_duplicate(theFilterMgr); + + QString aMode = QAD_CONFIG->getSetting("SMESH:DisplayMode"); + SetRepresentation(-1); + if(aMode.compare("Wireframe") == 0){ + SetRepresentation(eEdge); + }else if(aMode.compare("Shading") == 0){ + SetRepresentation(eSurface); + }else if(aMode.compare("Nodes") == 0){ + SetRepresentation(ePoint); } - else { - if ( myDisplayMode == 1 ) - EdgeDevice->GetProperty()->SetColor(edgePreselectedColor.r,edgePreselectedColor.g,edgePreselectedColor.b); - else if ( myDisplayMode == 2 ) - EdgeShrinkDevice->GetProperty()->SetColor(edgePreselectedColor.r,edgePreselectedColor.g,edgePreselectedColor.b); - else - this->GetProperty()->SetColor(actorPreselectedColor.r,actorPreselectedColor.g,actorPreselectedColor.b); + + aMode = QAD_CONFIG->getSetting("SMESH:Shrink"); + if(aMode == "yes"){ + SetShrink(); } - // is this actor opaque ? - if (this->GetIsOpaque()) { - this->Property->Render(this, ren); - - // render the backface property - if (this->BackfaceProperty) { - this->BackfaceProperty->BackfaceRender(this, ren); - } - - // render the texture - if (this->Texture) { - this->Texture->Render(ren); - } - this->Render(ren,this->Mapper); + Modified(); +} + + +vtkPolyData* SMESH_Actor::GetPolyDataInput(){ + return myPickableActor->GetPolyDataInput(); +} + + +void SMESH_Actor::SetTransform(SALOME_Transform* theTransform){ + myNodeActor->SetTransform(theTransform); + myBaseActor->SetTransform(theTransform); + myHighlitableActor->SetTransform(theTransform); + + my1DActor->SetTransform(theTransform); + my1DExtActor->SetTransform(theTransform); + + my2DActor->SetTransform(theTransform); + my3DActor->SetTransform(theTransform); + + Modified(); +} + + +void SMESH_Actor::SetUnstructuredGrid(vtkUnstructuredGrid* theGrid){ + if(theGrid){ + myNodeActor->SetUnstructuredGrid(theGrid); + myBaseActor->SetUnstructuredGrid(theGrid); + myHighlitableActor->SetUnstructuredGrid(theGrid); + + my1DActor->SetUnstructuredGrid(theGrid); + my1DExtActor->SetUnstructuredGrid(theGrid); + + my2DActor->SetUnstructuredGrid(theGrid); + my3DActor->SetUnstructuredGrid(theGrid); + + my1DActor->GetMapper()->SetLookupTable(myLookupTable); + my2DActor->GetMapper()->SetLookupTable(myLookupTable); + my3DActor->GetMapper()->SetLookupTable(myLookupTable); - renderedSomething = 1; + float aFactor, aUnits; + my2DActor->GetPolygonOffsetParameters(aFactor,aUnits); + my2DActor->SetPolygonOffsetParameters(aFactor,aUnits*0.75); + + //SetIsShrunkable(theGrid->GetNumberOfCells() > 10); + SetIsShrunkable(true); + + Modified(); } - - return renderedSomething; } -void SMESH_Actor::SetColor(float r,float g,float b) -{ - actorColor.r = r; - actorColor.g = g; - actorColor.b = b; +void SMESH_Actor::SetMapper(vtkMapper* theMapper){ + vtkLODActor::SetMapper(theMapper); } -void SMESH_Actor::GetColor(float& r,float& g,float& b) -{ - r = actorColor.r; - g = actorColor.g; - b = actorColor.b; + +void SMESH_Actor::ShallowCopy(vtkProp *prop){ + SALOME_Actor::ShallowCopy(prop); } -void SMESH_Actor::SetPreselectedColor(float r,float g,float b) -{ - actorPreselectedColor.r = r; - actorPreselectedColor.g = g; - actorPreselectedColor.b = b; + +vtkMapper* SMESH_Actor::GetMapper(){ + return myPickableActor->GetMapper(); } -void SMESH_Actor::GetPreselectedColor(float& r,float& g,float& b) -{ - r = actorPreselectedColor.r; - g = actorPreselectedColor.g; - b = actorPreselectedColor.b; + +vtkUnstructuredGrid* SMESH_Actor::GetUnstructuredGrid(){ + return myVisualObj->GetUnstructuredGrid(); } -void SMESH_Actor::SetHighlightColor(float r,float g,float b) -{ - actorHighlightColor.r = r; - actorHighlightColor.g = g; - actorHighlightColor.b = b; + +bool SMESH_Actor::IsInfinitive(){ + vtkDataSet *aDataSet = myPickableActor->GetUnstructuredGrid(); + aDataSet->Update(); + myIsInfinite = aDataSet->GetNumberOfCells() == 0; + return SALOME_Actor::IsInfinitive(); } -void SMESH_Actor::GetHighlightColor(float& r,float& g,float& b) -{ - r = actorHighlightColor.r; - g = actorHighlightColor.g; - b = actorHighlightColor.b; + +void SMESH_Actor::SetIsShrunkable(bool theShrunkable){ + myIsShrinkable = theShrunkable; + Modified(); } -void SMESH_Actor::SetEdgeColor(float r,float g,float b) -{ - edgeColor.r = r; - edgeColor.g = g; - edgeColor.b = b; +float SMESH_Actor::GetShrinkFactor(){ + return myBaseActor->GetShrinkFactor(); } -void SMESH_Actor::GetEdgeColor(float& r,float& g,float& b) -{ - r = edgeColor.r; - g = edgeColor.g; - b = edgeColor.b; +void SMESH_Actor::SetShrinkFactor(float theValue){ + myBaseActor->SetShrinkFactor(theValue); + + my1DActor->SetShrinkFactor(theValue); + my1DExtActor->SetShrinkFactor(theValue); + + my2DActor->SetShrinkFactor(theValue); + my3DActor->SetShrinkFactor(theValue); + + Modified(); } -void SMESH_Actor::SetEdgeHighlightColor(float r,float g,float b) -{ - edgeHighlightColor.r = r; - edgeHighlightColor.g = g; - edgeHighlightColor.b = b; +void SMESH_Actor::SetShrink(){ + if(!myIsShrinkable) return; + + myBaseActor->SetShrink(); + + my1DActor->SetShrink(); + my1DExtActor->SetShrink(); + + my2DActor->SetShrink(); + my3DActor->SetShrink(); + + myIsShrunk = true; + Modified(); } -void SMESH_Actor::GetEdgeHighlightColor(float& r,float& g,float& b) -{ - r = edgeHighlightColor.r; - g = edgeHighlightColor.g; - b = edgeHighlightColor.b; +void SMESH_Actor::UnShrink(){ + if(!myIsShrunk) return; + + myBaseActor->UnShrink(); + + my1DActor->UnShrink(); + my1DExtActor->UnShrink(); + + my2DActor->UnShrink(); + my3DActor->UnShrink(); + + myIsShrunk = false; + Modified(); } -void SMESH_Actor::SetEdgePreselectedColor(float r,float g,float b) -{ - edgePreselectedColor.r = r; - edgePreselectedColor.g = g; - edgePreselectedColor.b = b; + +int SMESH_Actor::GetObjId(int theVtkID){ + if (GetRepresentation() == 0){ + return GetNodeObjId(theVtkID); + }else{ + return GetElemObjId(theVtkID); + } } -void SMESH_Actor::GetEdgePreselectedColor(float& r,float& g,float& b) -{ - r = edgePreselectedColor.r; - g = edgePreselectedColor.g; - b = edgePreselectedColor.b; +SALOME_Actor::TVectorId SMESH_Actor::GetVtkId(int theObjID){ + if (GetRepresentation() == 0){ + return GetNodeVtkId(theObjID); + }else{ + return GetElemVtkId(theObjID); + } } -void SMESH_Actor::SetNodeColor(float r,float g,float b) -{ - actorNodeColor.r = r ; - actorNodeColor.g = g ; - actorNodeColor.b = b ; +int SMESH_Actor::GetNodeObjId(int theVtkID){ + return myPickableActor->GetNodeObjId(theVtkID); } -void SMESH_Actor::GetNodeColor(float& r,float& g,float& b) -{ - r = actorNodeColor.r ; - g = actorNodeColor.g ; - b = actorNodeColor.b ; +SALOME_Actor::TVectorId SMESH_Actor::GetNodeVtkId(int theObjID){ + return myPickableActor->GetNodeVtkId(theObjID); } -void SMESH_Actor::SetNodeSize(int size) -{ - actorNodeSize = size ; + +int SMESH_Actor::GetElemObjId(int theVtkID){ + return myPickableActor->GetElemObjId(theVtkID); } -int SMESH_Actor::GetNodeSize() -{ - return actorNodeSize ; +SALOME_Actor::TVectorId SMESH_Actor::GetElemVtkId(int theObjID){ + return myPickableActor->GetElemVtkId(theObjID); } -void SMESH_Actor::AddNode(int idSMESHDSnode,int idVTKnode) -{ - if (DataSource->IsA("SMESH_Grid")) { - ((SMESH_Grid*)DataSource)->AddNode(idSMESHDSnode, idVTKnode); - } else - MESSAGE("AddNode() method has been moved to SMESH_Grid class"); +void SMESH_Actor::SetVisibility(int theMode){ + SALOME_Actor::SetVisibility(theMode); + if(GetVisibility()){ + SetRepresentation(GetRepresentation()); + + if(myColorMode != eNone){ + if(my1DColorMode == e1DHighlited) + my1DExtActor->VisibilityOn(); + else if(myControlActor->GetUnstructuredGrid()->GetNumberOfCells()) + myScalarBarActor->VisibilityOn(); + } + + if(myRepresentation != ePoint) + myPickableActor->VisibilityOn(); + + my1DActor->VisibilityOn(); + + my2DActor->VisibilityOn(); + my3DActor->VisibilityOn(); + + if(myIsPointsLabeled) myPointLabels->VisibilityOn(); + if(myIsCellsLabeled) myCellsLabels->VisibilityOn(); + }else{ + myNodeActor->VisibilityOff(); + myBaseActor->VisibilityOff(); + + my1DActor->VisibilityOff(); + my1DExtActor->VisibilityOff(); + + my2DActor->VisibilityOff(); + my3DActor->VisibilityOff(); + + myScalarBarActor->VisibilityOff(); + myPointLabels->VisibilityOff(); + myCellsLabels->VisibilityOff(); + } + Modified(); } -void SMESH_Actor::AddElement(int idSMESHDSelement, int idVTKelement) -{ - if (DataSource->IsA("SMESH_Grid")) { - ((SMESH_Grid*)DataSource)->AddElement(idSMESHDSelement, idVTKelement); - } else - MESSAGE("AddElement() method has been moved to SMESH_Grid class"); + + +void SMESH_Actor::SetRepresentation(int theMode){ + int aNbEdges = myVisualObj->GetNbEntities(SMESH::EDGE); + int aNbFaces = myVisualObj->GetNbEntities(SMESH::FACE); + int aNbVolumes = myVisualObj->GetNbEntities(SMESH::VOLUME); + if(theMode < 0){ + myRepresentation = eSurface; + if(!aNbFaces && !aNbVolumes && aNbEdges){ + myRepresentation = eEdge; + }else if(!aNbFaces && !aNbVolumes && !aNbEdges){ + myRepresentation = ePoint; + } + }else{ + switch(theMode){ + case eEdge: + if(!aNbFaces && !aNbVolumes && !aNbEdges) return; + break; + case eSurface: + if(!aNbFaces && !aNbVolumes) return; + break; + } + myRepresentation = theMode; + } + + if(!GetUnstructuredGrid()->GetNumberOfCells()) + myRepresentation = ePoint; + + if(myIsShrunk){ + if(myRepresentation == ePoint){ + UnShrink(); + myIsShrunk = true; + }else{ + SetShrink(); + } + } + + myPickableActor = myBaseActor; + myNodeActor->SetVisibility(false); + vtkProperty *aProp = NULL, *aBackProp = NULL; + SMESH_DeviceActor::EReperesent aReperesent = SMESH_DeviceActor::EReperesent(-1); + switch(myRepresentation){ + case ePoint: + myPickableActor = myNodeActor; + aProp = aBackProp = myNodeProp; + aReperesent = SMESH_DeviceActor::ePoint; + break; + case eEdge: + aProp = aBackProp = myEdgeProp; + aReperesent = SMESH_DeviceActor::eInsideframe; + break; + case eSurface: + aProp = mySurfaceProp; + aBackProp = myBackSurfaceProp; + aReperesent = SMESH_DeviceActor::eSurface; + break; + } + + my2DActor->SetProperty(aProp); + my2DActor->SetBackfaceProperty(aBackProp); + my2DActor->SetRepresentation(aReperesent); + + my3DActor->SetProperty(aProp); + my3DActor->SetBackfaceProperty(aBackProp); + my3DActor->SetRepresentation(aReperesent); + + my1DExtActor->SetVisibility(false); + switch(my1DColorMode){ + case e1DColored: + aProp = aBackProp = my1DProp; + if(myRepresentation != ePoint) + aReperesent = SMESH_DeviceActor::eInsideframe; + break; + case e1DHighlited: + my1DExtActor->SetVisibility(true); + break; + } + + my1DActor->SetProperty(aProp); + my1DActor->SetBackfaceProperty(aBackProp); + my1DActor->SetRepresentation(aReperesent); + + if ( GetPointRepresentation() || !GetUnstructuredGrid()->GetNumberOfCells() || myIsPointsLabeled ) + { + myPickableActor = myNodeActor; + myNodeActor->SetVisibility(true); + } + + SetMapper(myPickableActor->GetMapper()); + + Modified(); } -void SMESH_Actor::SetIdsVTKNode(const TColStd_DataMapOfIntegerInteger& mapVTK) -{ - if (DataSource->IsA("SMESH_Grid")) { - ((SMESH_Grid*)DataSource)->SetIdsVTKNode(mapVTK); - } else - MESSAGE("SetIdsVTKNode() method has been moved to SMESH_Grid class"); + +void SMESH_Actor::SetPointRepresentation(int theIsPointsVisible){ + myIsPointsVisible = theIsPointsVisible; + SetRepresentation(GetRepresentation()); } -void SMESH_Actor::SetIdsSMESHDSNode(const TColStd_DataMapOfIntegerInteger& mapSMESHDS) -{ - if (DataSource->IsA("SMESH_Grid")) { - ((SMESH_Grid*)DataSource)->SetIdsSMESHDSNode(mapSMESHDS); - } else - MESSAGE("SetIdsSMESHDSNode() method has been moved to SMESH_Grid class"); + + +void SMESH_Actor::UpdateHighlight(){ + myHighlitableActor->SetVisibility(false); + myNodeActor->SetProperty(myNodeProp); + if(myPickableActor != myNodeActor) + myNodeActor->SetVisibility(false); + + if(ishighlighted){ + myHighlitableActor->SetProperty(myHighlightProp); + }else if(ispreselected){ + myHighlitableActor->SetProperty(myPreselectProp); + } + + if(ishighlighted || ispreselected){ + if(!GetUnstructuredGrid()->GetNumberOfCells()){ + myNodeActor->SetProperty(myHighlitableActor->GetProperty()); + myNodeActor->SetRepresentation(SMESH_DeviceActor::ePoint); + myNodeActor->SetVisibility(GetVisibility()); + }else{ + myHighlitableActor->SetRepresentation(SMESH_DeviceActor::eWireframe); + myHighlitableActor->SetVisibility(GetVisibility()); + } + } } -void SMESH_Actor::SetIdsVTKElement(const TColStd_DataMapOfIntegerInteger& mapVTK) -{ - if (DataSource->IsA("SMESH_Grid")) { - ((SMESH_Grid*)DataSource)->SetIdsVTKElement(mapVTK); - } else - MESSAGE("SetIdsVTKElement() method has been moved to SMESH_Grid class"); + +void SMESH_Actor::highlight(Standard_Boolean highlight){ + ishighlighted = highlight; + UpdateHighlight(); } -void SMESH_Actor::SetIdsSMESHDSElement(const TColStd_DataMapOfIntegerInteger& mapSMESHDS) -{ - if (DataSource->IsA("SMESH_Grid")) { - ((SMESH_Grid*)DataSource)->SetIdsSMESHDSElement(mapSMESHDS); - } else - MESSAGE("SetIdsSMESHDSElement() method has been moved to SMESH_Grid class"); + + +void SMESH_Actor::SetPreSelected(Standard_Boolean presel){ + ispreselected = presel; + UpdateHighlight(); } -int SMESH_Actor::GetIdVTKNode(int idSMESHDSnode) + +// From vtkFollower +int SMESH_Actor::RenderOpaqueGeometry(vtkViewport *vp) { - if (DataSource->IsA("SMESH_Grid")) { - return ((SMESH_Grid*)DataSource)->GetIdVTKNode(idSMESHDSnode); - } else { - MESSAGE("GetIdVTKNode() method has been moved to SMESH_Grid class"); - return -1; - } + if (myPickableActor->GetIsOpaque()) + { + vtkRenderer *ren = static_cast(vp); + this->Render(ren); + return 1; + } + return 0; } -int SMESH_Actor::GetIdVTKElement(int idSMESHDSelement) + + +int SMESH_Actor::RenderTranslucentGeometry(vtkViewport *vp) { - if (DataSource->IsA("SMESH_Grid")) { - return ((SMESH_Grid*)DataSource)->GetIdVTKElement(idSMESHDSelement); - } else { - MESSAGE("GetIdVTKElement() method has been moved to SMESH_Grid class"); - return -1; - } + if (!myPickableActor->GetIsOpaque()) + { + vtkRenderer *ren = static_cast(vp); + this->Render(ren); + return 1; + } + return 0; +} + + +void SMESH_Actor::Render(vtkRenderer *ren){} + +void SMESH_Actor::ReleaseGraphicsResources(vtkWindow *renWin){ + SALOME_Actor::ReleaseGraphicsResources(renWin); + + myPickableActor->ReleaseGraphicsResources(renWin); } -int SMESH_Actor::GetIdSMESHDSNode(int idVTKnode) -{ - if (DataSource->IsA("SMESH_Grid")) { - return ((SMESH_Grid*)DataSource)->GetIdSMESHDSNode(idVTKnode); - } else { - MESSAGE("GetIdSMESHDSNode() method has been moved to SMESH_Grid class"); - return -1; - } + +static void GetColor(vtkProperty *theProperty, float& r,float& g,float& b){ + float* aColor = theProperty->GetColor(); + r = aColor[0]; + g = aColor[1]; + b = aColor[2]; } -int SMESH_Actor::GetIdSMESHDSElement(int idVTKelement) -{ - if (DataSource->IsA("SMESH_Grid")) { - return ((SMESH_Grid*)DataSource)->GetIdSMESHDSElement(idVTKelement); - } else { - MESSAGE("AddNode() method has been moved to SMESH_Grid class"); - return -1; - } + +void SMESH_Actor::SetOpacity(float theValue){ + mySurfaceProp->SetOpacity(theValue); + myBackSurfaceProp->SetOpacity(theValue); + myEdgeProp->SetOpacity(theValue); + myNodeProp->SetOpacity(theValue); + + my1DProp->SetOpacity(theValue); } -void SMESH_Actor::ClearNode() -{ - if (DataSource->IsA("SMESH_Grid")) { - ((SMESH_Grid*)DataSource)->ClearNode(); - } else - MESSAGE("ClearNode() method has been moved to SMESH_Grid class"); + +float SMESH_Actor::GetOpacity(){ + return mySurfaceProp->GetOpacity(); } -void SMESH_Actor::ClearElement() -{ - if (DataSource->IsA("SMESH_Grid")) { - ((SMESH_Grid*)DataSource)->ClearElement(); - } else - MESSAGE("ClearElement() method has been moved to SMESH_Grid class"); + +void SMESH_Actor::SetSufaceColor(float r,float g,float b){ + mySurfaceProp->SetColor(r,g,b); + Modified(); } -void SMESH_Actor::RemoveNode(int id) -{ - if (DataSource->IsA("SMESH_Grid")) { - ((SMESH_Grid*)DataSource)->RemoveNode(id); - } else - MESSAGE("RemoveNode() method has been moved to SMESH_Grid class"); +void SMESH_Actor::GetSufaceColor(float& r,float& g,float& b){ + ::GetColor(mySurfaceProp,r,g,b); } -void SMESH_Actor::RemoveElement(int id) -{ - if (DataSource->IsA("SMESH_Grid")) { - ((SMESH_Grid*)DataSource)->RemoveElement(id); - } else - MESSAGE("RemoveElement() method has been moved to SMESH_Grid class"); -} - -void SMESH_Actor::setDisplayMode(int thenewmode) { - myDisplayMode = thenewmode; - if ( myDisplayMode == 1 ) { - EdgeDevice->VisibilityOn(); - EdgeShrinkDevice->VisibilityOff(); - } else if ( myDisplayMode == 2 ) { - EdgeDevice->VisibilityOff(); - EdgeShrinkDevice->VisibilityOn(); - } else { - EdgeDevice->VisibilityOff(); - EdgeShrinkDevice->VisibilityOff(); - } + +void SMESH_Actor::SetBackSufaceColor(float r,float g,float b){ + myBackSurfaceProp->SetColor(r,g,b); + Modified(); } -float SMESH_Actor::GetShrinkFactor() -{ - return myShrinkFactor; +void SMESH_Actor::GetBackSufaceColor(float& r,float& g,float& b){ + ::GetColor(myBackSurfaceProp,r,g,b); } -void SMESH_Actor::SetShrinkFactor(float value ) -{ - if ( value <= 0.1 ) - value = 0.8; +void SMESH_Actor::SetEdgeColor(float r,float g,float b){ + myEdgeProp->SetColor(r,g,b); + my1DProp->SetColor(r,g,b); + my1DExtProp->SetColor(1.0-r,1.0-g,1.0-b); + Modified(); +} - myShrinkFactor = value; +void SMESH_Actor::GetEdgeColor(float& r,float& g,float& b){ + ::GetColor(myEdgeProp,r,g,b); } -void SMESH_Actor::GetChildActors(vtkActorCollection* actors) -{ - actors->AddItem(EdgeDevice); - actors->AddItem(EdgeShrinkDevice); +void SMESH_Actor::SetNodeColor(float r,float g,float b){ + myNodeProp->SetColor(r,g,b); + Modified(); } -void SMESH_Actor::SetVisibility(bool visibility) -{ - if ( visibility ) { - this->VisibilityOn(); - if ( myDisplayMode == 1 ) { - EdgeDevice->VisibilityOn(); - EdgeShrinkDevice->VisibilityOff(); - } else if ( myDisplayMode == 2 ) { - EdgeDevice->VisibilityOff(); - EdgeShrinkDevice->VisibilityOn(); - } else { - EdgeDevice->VisibilityOff(); - EdgeShrinkDevice->VisibilityOff(); - } - } else { - this->VisibilityOff(); - EdgeDevice->VisibilityOff(); - EdgeShrinkDevice->VisibilityOff(); - } +void SMESH_Actor::GetNodeColor(float& r,float& g,float& b){ + ::GetColor(myNodeProp,r,g,b); +} + +void SMESH_Actor::SetHighlightColor(float r,float g,float b){ + myHighlightProp->SetColor(r,g,b); + Modified(); +} + +void SMESH_Actor::GetHighlightColor(float& r,float& g,float& b){ + ::GetColor(myHighlightProp,r,g,b); +} + +void SMESH_Actor::SetPreHighlightColor(float r,float g,float b){ + myPreselectProp->SetColor(r,g,b); + Modified(); } +void SMESH_Actor::GetPreHighlightColor(float& r,float& g,float& b){ + ::GetColor(myPreselectProp,r,g,b); +} + + +float SMESH_Actor::GetLineWidth(){ + return myEdgeProp->GetLineWidth(); +} + + +void SMESH_Actor::SetLineWidth(float theVal){ + myEdgeProp->SetLineWidth(theVal); + Modified(); +} + + +void SMESH_Actor::SetNodeSize(float theSize){ + myNodeProp->SetPointSize(theSize); + myHighlightProp->SetPointSize(theSize); + myPreselectProp->SetPointSize(theSize); + + my1DExtProp->SetPointSize(theSize); + my1DProp->SetPointSize(theSize); + + Modified(); +} + +float SMESH_Actor::GetNodeSize(){ + return myNodeProp->GetPointSize(); +} + +int SMESH_Actor::GetObjDimension( const int theObjId ) +{ + return myVisualObj->GetElemDimension( theObjId ); +} diff --git a/src/OBJECT/SMESH_Actor.h b/src/OBJECT/SMESH_Actor.h index ced5ade24..2cb9628a8 100644 --- a/src/OBJECT/SMESH_Actor.h +++ b/src/OBJECT/SMESH_Actor.h @@ -30,126 +30,205 @@ #define SMESH_ACTOR_H #include "SALOME_Actor.h" +#include "SMESH_Object.h" -// VTK Includes -#include -#include -#include +class vtkProperty; +class vtkShrinkFilter; +class vtkPolyDataMapper; +class vtkUnstructuredGrid; +class vtkMergeFilter; +class vtkPolyData; -// Open CASCADE Includes -#include -#include +class vtkMapper; +class vtkActor2D; +class vtkMaskPoints; +class vtkLabeledDataMapper; +class vtkSelectVisiblePoints; -typedef struct rgbStruct -{ - float r; - float g; - float b; -} RGBStruct; +class vtkScalarBarActor; +class vtkLookupTable; -class SMESH_Actor : public SALOME_Actor { +class SMESH_DeviceActor; +class SALOME_ExtractUnstructuredGrid; - public: - vtkTypeMacro(SMESH_Actor,SALOME_Actor); - - static SMESH_Actor* New(); - // Description: - // This causes the actor to be rendered. It, in turn, will render the actor`s - // property and then mapper. - virtual void Render(vtkRenderer *, vtkMapper *); +class SMESH_Actor : public SALOME_Actor{ + friend class SMESH_VisualObj; - // Description: - // This method is used internally by the rendering process. - // We overide the superclass method to properly set the estimated render time. - int RenderOpaqueGeometry(vtkViewport *viewport); - - void ShallowCopy(vtkProp *prop); - - void setReader(vtkUnstructuredGridReader* r) ; - vtkUnstructuredGridReader* getReader(); + public: + vtkTypeMacro(SMESH_Actor,SALOME_Actor); + static SMESH_Actor* New(TVisualObjPtr theVisualObj, + SMESH::FilterManager_ptr theFilterMgr, + const char* theEntry, + const char* theName, + int theIsClear); + + virtual void ReleaseGraphicsResources(vtkWindow *renWin); + virtual int RenderOpaqueGeometry(vtkViewport *viewport); + virtual int RenderTranslucentGeometry(vtkViewport *viewport); + virtual void Render(vtkRenderer *ren); + + virtual void AddToRender(vtkRenderer* theRenderer); + virtual void RemoveFromRender(vtkRenderer* theRenderer); - // Highlight virtual bool hasHighlight() { return true; } + virtual void highlight(Standard_Boolean highlight); + virtual void SetPreSelected(Standard_Boolean presel = Standard_False); - vtkMapper* getMapper(); + virtual bool IsInfinitive(); - void setDisplayMode(int); + virtual void SetOpacity(float theValue); + virtual float GetOpacity(); - void SetColor(float r,float g,float b); - void GetColor(float& r,float& g,float& b); - void SetHighlightColor(float r,float g,float b); - void GetHighlightColor(float& r,float& g,float& b); - void SetPreselectedColor(float r,float g,float b); - void GetPreselectedColor(float& r,float& g,float& b); + void SetSufaceColor(float r,float g,float b); + void GetSufaceColor(float& r,float& g,float& b); + + void SetBackSufaceColor(float r,float g,float b); + void GetBackSufaceColor(float& r,float& g,float& b); void SetEdgeColor(float r,float g,float b); void GetEdgeColor(float& r,float& g,float& b); - void SetEdgeHighlightColor(float r,float g,float b); - void GetEdgeHighlightColor(float& r,float& g,float& b); - void SetEdgePreselectedColor(float r,float g,float b); - void GetEdgePreselectedColor(float& r,float& g,float& b); void SetNodeColor(float r,float g,float b); void GetNodeColor(float& r,float& g,float& b); + + void SetHighlightColor(float r,float g,float b); + void GetHighlightColor(float& r,float& g,float& b); + + void SetPreHighlightColor(float r,float g,float b); + void GetPreHighlightColor(float& r,float& g,float& b); - void SetNodeSize(int size) ; - int GetNodeSize() ; + float GetLineWidth(); + void SetLineWidth(float theVal); + void SetNodeSize(float size) ; + float GetNodeSize() ; - void ClearNode(); - void ClearElement(); + virtual int GetObjId(int theVtkID); + virtual TVectorId GetVtkId(int theObjID); - void RemoveNode(int idSMESHDSnode); - void RemoveElement(int idSMESHDSelement); + virtual int GetNodeObjId(int theVtkID); + virtual TVectorId GetNodeVtkId(int theObjID); - void AddNode(int idSMESHDSnode, int idVTKnode); - void AddElement(int idSMESHDSelement, int idVTKelement); + virtual int GetElemObjId(int theVtkID); + virtual TVectorId GetElemVtkId(int theObjID); - int GetIdVTKNode(int idSMESHDSnode); - int GetIdVTKElement(int idSMESHDSelement); + virtual int GetObjDimension( const int theObjId ); - int GetIdSMESHDSNode(int idVTKnode); - int GetIdSMESHDSElement(int idVTKelement); + virtual void SetVisibility(int theMode); - void SetIdsVTKNode(const TColStd_DataMapOfIntegerInteger& mapVTK); - void SetIdsSMESHDSNode(const TColStd_DataMapOfIntegerInteger& mapSMESHDS); + enum EReperesent { ePoint, eEdge, eSurface}; + virtual void SetRepresentation(int theMode); + void SetPointRepresentation(int theIsPointsVisible); + bool GetPointRepresentation(){ return myIsPointsVisible;} - void SetIdsVTKElement(const TColStd_DataMapOfIntegerInteger& mapVTK); - void SetIdsSMESHDSElement(const TColStd_DataMapOfIntegerInteger& mapSMESHDS); + virtual vtkPolyData* GetPolyDataInput(); + virtual void SetTransform(SALOME_Transform* theTransform); - vtkDataSet* DataSource; - vtkActor* EdgeDevice; - vtkActor* EdgeShrinkDevice; + vtkUnstructuredGrid* GetUnstructuredGrid(); + virtual vtkMapper* GetMapper(); float GetShrinkFactor(); void SetShrinkFactor(float value ); - void GetChildActors(vtkActorCollection*); + bool IsShrunkable() { return myIsShrinkable;} + bool IsShrunk() { return myIsShrunk;} + void SetShrink(); + void UnShrink(); - void SetVisibility(bool visibility); + void SetPointsLabeled(bool theIsPointsLabeled); + bool GetPointsLabeled(){ return myIsPointsLabeled;} - protected: + void SetCellsLabeled(bool theIsCellsLabeled); + bool GetCellsLabeled(){ return myIsCellsLabeled;} - SMESH_Actor(); - ~SMESH_Actor(); - SMESH_Actor(const SMESH_Actor&) {}; - void operator=(const SMESH_Actor&) {}; + enum eControl{eNone, eLengthEdges, eFreeBorders, eMultiConnection, + eArea, eTaper, eAspectRatio, eMinimumAngle, eWarping, eSkew}; + void SetControlMode(eControl theMode); + eControl GetControlMode(){ return myColorMode;} + + enum e1DControl{e1DNone, e1DColored, e1DHighlited}; + e1DControl Get1DControlMode(){ return my1DColorMode;} - vtkUnstructuredGridReader* myReader; + vtkScalarBarActor* GetScalarBarActor(){ return myScalarBarActor;} - float myShrinkFactor; + TVisualObjPtr GetObject() { return myVisualObj;} - RGBStruct edgeColor; - RGBStruct edgeHighlightColor; - RGBStruct edgePreselectedColor; + protected: + TVisualObjPtr myVisualObj; + + SMESH::FilterManager_var myFilterMgr; + vtkScalarBarActor* myScalarBarActor; + vtkLookupTable* myLookupTable; + + vtkProperty* mySurfaceProp; + vtkProperty* myBackSurfaceProp; + vtkProperty* myEdgeProp; + vtkProperty* myNodeProp; + + SMESH_DeviceActor* myBaseActor; + SMESH_DeviceActor* myNodeActor; + SMESH_DeviceActor* myPickableActor; + + vtkProperty* myHighlightProp; + vtkProperty* myPreselectProp; + SMESH_DeviceActor* myHighlitableActor; + + eControl myColorMode; + SMESH_DeviceActor* my2DActor; + SMESH_DeviceActor* my3DActor; + SMESH_DeviceActor* myControlActor; + + e1DControl my1DColorMode; + vtkProperty* my1DProp; + SMESH_DeviceActor* my1DActor; + vtkProperty* my1DExtProp; + SMESH_DeviceActor* my1DExtActor; + + bool myIsPointsVisible; + + bool myIsShrinkable; + bool myIsShrunk; + + bool myIsPointsLabeled; + vtkUnstructuredGrid* myPointsNumDataSet; + vtkActor2D *myPointLabels; + vtkMaskPoints* myPtsMaskPoints; + vtkLabeledDataMapper* myPtsLabeledDataMapper; + vtkSelectVisiblePoints* myPtsSelectVisiblePoints; + + bool myIsCellsLabeled; + vtkUnstructuredGrid* myCellsNumDataSet; + vtkActor2D *myCellsLabels; + vtkMaskPoints* myClsMaskPoints; + vtkCellCenters* myCellCenters; + vtkLabeledDataMapper* myClsLabeledDataMapper; + vtkSelectVisiblePoints* myClsSelectVisiblePoints; - RGBStruct actorColor; - RGBStruct actorHighlightColor; - RGBStruct actorPreselectedColor; + SMESH_Actor(); + ~SMESH_Actor(); - RGBStruct actorNodeColor; // LPN - int actorNodeSize; // LPN + void Init(TVisualObjPtr theVisualObj, + SMESH::FilterManager_ptr theFilterMgr, + const char* theEntry, + const char* theName, + int theIsClear); + + void SetUnstructuredGrid(vtkUnstructuredGrid* theGrid); + void SetIsShrunkable(bool theShrunkable); + void UpdateHighlight(); + + private: + // hide the two parameter Render() method from the user and the compiler. + virtual void Render(vtkRenderer *, vtkMapper *) {}; + virtual void ShallowCopy(vtkProp *prop); + virtual void SetMapper(vtkMapper *); + static SMESH_Actor* New(); + // Not implemented. + SMESH_Actor(const SMESH_Actor&); + void operator=(const SMESH_Actor&); }; + + #endif //SMESH_ACTOR_H diff --git a/src/OBJECT/SMESH_DeviceActor.cxx b/src/OBJECT/SMESH_DeviceActor.cxx new file mode 100644 index 000000000..950bf83cd --- /dev/null +++ b/src/OBJECT/SMESH_DeviceActor.cxx @@ -0,0 +1,357 @@ +// SMESH OBJECT : interactive object for SMESH visualization +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_Actor.cxx +// Author : Nicolas REJNERI +// Module : SMESH +// $Header$ + + +#include "SMESH_DeviceActor.h" + +#include "SALOME_Transform.h" +#include "SALOME_TransformFilter.h" +#include "SALOME_PassThroughFilter.h" +#include "SALOME_ExtractUnstructuredGrid.h" + +#include "utilities.h" + +// VTK Includes +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifdef _DEBUG_ +static int MYDEBUG = 0; +static int MYDEBUGWITHFILES = 0; +#else +static int MYDEBUG = 0; +static int MYDEBUGWITHFILES = 0; +#endif + +using namespace std; + + +vtkStandardNewMacro(SMESH_DeviceActor); + + +SMESH_DeviceActor::SMESH_DeviceActor(){ + if(MYDEBUG) MESSAGE("SMESH_DeviceActor"); + myIsShrunk = false; + myIsShrinkable = false; + myRepresentation = eSurface; + + myProperty = vtkProperty::New(); + myMapper = vtkPolyDataMapper::New(); + + vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters(myPolygonOffsetFactor, + myPolygonOffsetUnits); + //myMapper->SetResolveCoincidentTopologyToShiftZBuffer(); + //myMapper->SetResolveCoincidentTopologyZShift(0.02); + + myMapper->UseLookupTableScalarRangeOn(); + myMapper->SetColorModeToMapScalars(); + + myShrinkFilter = vtkShrinkFilter::New(); + + myExtractUnstructuredGrid = SALOME_ExtractUnstructuredGrid::New(); + myExtractUnstructuredGrid->SetStoreMapping(true); + + myMergeFilter = vtkMergeFilter::New(); + + myStoreMapping = false; + myGeomFilter = SALOME_GeometryFilter::New(); + + myTransformFilter = SALOME_TransformFilter::New(); + + for(int i = 0; i < 6; i++) + myPassFilter.push_back(SALOME_PassThroughFilter::New()); +} + + +SMESH_DeviceActor::~SMESH_DeviceActor(){ + if(MYDEBUG) MESSAGE("~SMESH_DeviceActor"); + myProperty->Delete(); + + myMapper->RemoveAllInputs(); + myMapper->Delete(); + + myShrinkFilter->UnRegisterAllOutputs(); + myShrinkFilter->Delete(); + + myExtractUnstructuredGrid->UnRegisterAllOutputs(); + myExtractUnstructuredGrid->Delete(); + + myMergeFilter->UnRegisterAllOutputs(); + myMergeFilter->Delete(); + + myGeomFilter->UnRegisterAllOutputs(); + myGeomFilter->Delete(); + + myTransformFilter->UnRegisterAllOutputs(); + myTransformFilter->Delete(); + + for(int i = 0, iEnd = myPassFilter.size(); i < iEnd; i++){ + myPassFilter[i]->UnRegisterAllOutputs(); + myPassFilter[i]->Delete(); + } +} + + +void SMESH_DeviceActor::SetStoreMapping(int theStoreMapping){ + myStoreMapping = theStoreMapping; + Modified(); +} + + +void SMESH_DeviceActor::SetUnstructuredGrid(vtkUnstructuredGrid* theGrid){ + if(theGrid){ + //myIsShrinkable = theGrid->GetNumberOfCells() > 10; + myIsShrinkable = true; + + myExtractUnstructuredGrid->SetInput(theGrid); + myMergeFilter->SetGeometry(myExtractUnstructuredGrid->GetOutput()); + + theGrid = static_cast(myMergeFilter->GetOutput()); + + int anId = 0; + myPassFilter.at( anId )->SetInput( theGrid ); + myPassFilter.at( anId + 1)->SetInput( myPassFilter.at( anId )->GetOutput() ); + + anId++; // 1 + myGeomFilter->SetStoreMapping( myStoreMapping ); + myGeomFilter->SetInput( myPassFilter.at( anId )->GetOutput() ); + + anId++; // 2 + myPassFilter.at( anId )->SetInput( myGeomFilter->GetOutput() ); + myPassFilter.at( anId + 1 )->SetInput( myPassFilter.at( anId )->GetOutput() ); + + anId++; // 3 + myTransformFilter->SetInput( myPassFilter.at( anId )->GetPolyDataOutput() ); + + anId++; // 4 + myPassFilter.at( anId )->SetInput( myTransformFilter->GetOutput() ); + myPassFilter.at( anId + 1 )->SetInput( myPassFilter.at( anId )->GetOutput() ); + + anId++; // 5 + myMapper->SetInput( myPassFilter.at( anId )->GetPolyDataOutput() ); + + vtkLODActor::SetMapper( myMapper ); + Modified(); + } +} + + +SALOME_ExtractUnstructuredGrid* SMESH_DeviceActor::GetExtractUnstructuredGrid(){ + return myExtractUnstructuredGrid; +} + + +vtkUnstructuredGrid* SMESH_DeviceActor::GetUnstructuredGrid(){ + myExtractUnstructuredGrid->Update(); + return myExtractUnstructuredGrid->GetOutput(); +} + + +vtkMergeFilter* SMESH_DeviceActor::GetMergeFilter(){ + return myMergeFilter; +} + + +vtkPolyData* SMESH_DeviceActor::GetPolyDataInput(){ + return myPassFilter.back()->GetPolyDataOutput(); +} + + +unsigned long int SMESH_DeviceActor::GetMTime(){ + unsigned long mTime = this->Superclass::GetMTime(); + mTime = max(mTime,myExtractUnstructuredGrid->GetMTime()); + mTime = max(mTime,myMergeFilter->GetMTime()); + mTime = max(mTime,myGeomFilter->GetMTime()); + mTime = max(mTime,myTransformFilter->GetMTime()); + return mTime; +} + + +void SMESH_DeviceActor::SetTransform(SALOME_Transform* theTransform){ + myTransformFilter->SetTransform(theTransform); +} + + +void SMESH_DeviceActor::SetShrink() +{ + if ( !myIsShrinkable ) return; + if ( vtkDataSet* aDataSet = myPassFilter.at( 0 )->GetOutput() ) + { + myShrinkFilter->SetInput( aDataSet ); + myPassFilter.at( 1 )->SetInput( myShrinkFilter->GetOutput() ); + myIsShrunk = true; + } +} + +void SMESH_DeviceActor::UnShrink() +{ + if ( !myIsShrunk ) return; + if ( vtkDataSet* aDataSet = myPassFilter.at( 0 )->GetOutput() ) + { + myPassFilter.at( 1 )->SetInput( aDataSet ); + myPassFilter.at( 1 )->Modified(); + myIsShrunk = false; + Modified(); + } +} + + +void SMESH_DeviceActor::SetRepresentation(EReperesent theMode){ + switch(theMode){ + case ePoint: + myGeomFilter->SetInside(true); + GetProperty()->SetRepresentation(0); + break; + case eInsideframe: + myGeomFilter->SetInside(true); + GetProperty()->SetRepresentation(1); + break; + default : + GetProperty()->SetRepresentation(theMode); + myGeomFilter->SetInside(false); + } + myRepresentation = theMode; + myMapper->Modified(); + Modified(); +} + + +void SMESH_DeviceActor::SetVisibility(int theMode){ + if(!myExtractUnstructuredGrid->GetInput() || GetUnstructuredGrid()->GetNumberOfCells()){ + vtkLODActor::SetVisibility(theMode); + }else{ + vtkLODActor::SetVisibility(false); + } +} + + +int SMESH_DeviceActor::GetVisibility(){ + if(!GetUnstructuredGrid()->GetNumberOfCells()){ + vtkLODActor::SetVisibility(false); + } + return vtkLODActor::GetVisibility(); +} + + +int SMESH_DeviceActor::GetObjId(int theVtkID){ + if (GetRepresentation() == ePoint){ + return GetNodeObjId(theVtkID); + }else{ + return GetElemObjId(theVtkID); + } +} + + +SMESH_DeviceActor::TVectorId SMESH_DeviceActor::GetVtkId(int theObjID){ + if (GetRepresentation() == ePoint){ + return GetNodeVtkId(theObjID); + }else{ + return GetElemVtkId(theObjID); + } +} + + +int SMESH_DeviceActor::GetNodeObjId(int theVtkID){ + vtkIdType aRetID = myVisualObj->GetNodeObjId(theVtkID); + if(MYDEBUG) MESSAGE("GetNodeObjId - theVtkID = "< + +class vtkProperty; +class vtkMergeFilter; +class vtkShrinkFilter; +class vtkPolyDataMapper; +class vtkUnstructuredGrid; + +class SALOME_Transform; +class SALOME_TransformFilter; +class SALOME_PassThroughFilter; +class SALOME_ExtractUnstructuredGrid; + + +class SMESH_DeviceActor: public vtkLODActor{ + friend class SMESH_Actor; + + public: + vtkTypeMacro(SMESH_DeviceActor,vtkLODActor); + static SMESH_DeviceActor* New(); + + void SetStoreMapping(int theStoreMapping); + int GetStoreMapping(){ return myStoreMapping;} + + typedef SALOME_GeometryFilter::TVectorId TVectorId; + int GetObjId(int theVtkID); + TVectorId GetVtkId(int theObjID); + + int GetNodeObjId(int theVtkID); + TVectorId GetNodeVtkId(int theObjID); + + int GetElemObjId(int theVtkID); + TVectorId GetElemVtkId(int theObjID); + + vtkPolyData* GetPolyDataInput(); + + virtual void SetTransform(SALOME_Transform* theTransform); + virtual unsigned long int GetMTime(); + + float GetShrinkFactor(); + void SetShrinkFactor(float value); + + bool IsShrunkable() { return myIsShrinkable;} + bool IsShrunk() { return myIsShrunk;} + void SetShrink(); + void UnShrink(); + + enum EReperesent { ePoint, eWireframe, eSurface, eInsideframe}; + EReperesent GetRepresentation(){ return myRepresentation;} + void SetRepresentation(EReperesent theMode); + + virtual void SetVisibility(int theMode); + virtual int GetVisibility(); + + SALOME_ExtractUnstructuredGrid* GetExtractUnstructuredGrid(); + vtkUnstructuredGrid* GetUnstructuredGrid(); + vtkMergeFilter* GetMergeFilter(); + + virtual void Render(vtkRenderer *, vtkMapper *); + + protected: + void SetUnstructuredGrid(vtkUnstructuredGrid* theGrid); + + vtkPolyDataMapper *myMapper; + TVisualObjPtr myVisualObj; + + vtkProperty *myProperty; + EReperesent myRepresentation; + + vtkMergeFilter* myMergeFilter; + SALOME_ExtractUnstructuredGrid* myExtractUnstructuredGrid; + + bool myStoreMapping; + SALOME_GeometryFilter *myGeomFilter; + SALOME_TransformFilter *myTransformFilter; + std::vector myPassFilter; + + vtkShrinkFilter* myShrinkFilter; + bool myIsShrinkable; + bool myIsShrunk; + + float myPolygonOffsetFactor; + float myPolygonOffsetUnits; + + void SetPolygonOffsetParameters(float factor, float units); + void GetPolygonOffsetParameters(float& factor, float& units){ + factor = myPolygonOffsetFactor; + units = myPolygonOffsetUnits; + } + + SMESH_DeviceActor(); + ~SMESH_DeviceActor(); + SMESH_DeviceActor(const SMESH_DeviceActor&) {}; + void operator=(const SMESH_DeviceActor&) {}; + +}; + + +#endif //SMESH_ACTOR_H diff --git a/src/OBJECT/SMESH_Object.cxx b/src/OBJECT/SMESH_Object.cxx new file mode 100644 index 000000000..eb39610cb --- /dev/null +++ b/src/OBJECT/SMESH_Object.cxx @@ -0,0 +1,1037 @@ +// SMESH OBJECT : interactive object for SMESH visualization +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_Grid.cxx +// Author : Nicolas REJNERI +// Module : SMESH + +#include "SMESH_Object.h" +#include "SMDS_Mesh.hxx" +#include "SALOME_ExtractUnstructuredGrid.h" +#include "SMESH_Actor.h" + +#include CORBA_SERVER_HEADER(SALOME_Exception) + +#include +#include +#include + +#include +#include +#include +#include + +#include "utilities.h" + +using namespace std; + +#ifndef EXCEPTION +#define EXCEPTION(TYPE, MSG) {\ + std::ostringstream aStream;\ + aStream<<__FILE__<<"["<<__LINE__<<"]::"<SetFileName(theFileName); + aWriter->SetInput(theGrid); + aWriter->Write(); + aWriter->Delete(); +} + + +namespace{ + + inline const SMDS_MeshNode* FindNode(const SMDS_Mesh* theMesh, int theId){ + if(const SMDS_MeshNode* anElem = theMesh->FindNode(theId)) return anElem; + EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<FindElement(theId)) return anElem; + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot find a SMDS_MeshElement for ID = "<AddNodeWithID(aCoords[aCoordId], + aCoords[aCoordId+1], + aCoords[aCoordId+2], + anIndexes[anElemId]); + if(!anElem) + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddNodeWithID for ID = "<AddEdgeWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId+2], + anIndexes[anIndexId]); + if(!anElem) + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddEdgeWithID for ID = "<AddFaceWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId]); + if(!anElem) + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<AddFaceWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId]); + if(!anElem) + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<AddVolumeWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId]); + if(!anElem) + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<AddVolumeWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId+5], + anIndexes[anIndexId]); + if(!anElem) + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<AddVolumeWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId+5], + anIndexes[anIndexId+6], + anIndexes[anIndexId]); + if(!anElem) + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<AddVolumeWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId+5], + anIndexes[anIndexId+6], + anIndexes[anIndexId+7], + anIndexes[anIndexId+8], + anIndexes[anIndexId]); + if(!anElem) + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<GetReferenceCount() = " << myGrid->GetReferenceCount() ); + myGrid->Delete(); +} + +//================================================================================= +// functions : GetNodeObjId, GetNodeVTKId, GetElemObjId, GetElemVTKId +// purpose : Methods for retrieving VTK IDs by SMDS IDs and vice versa +//================================================================================= +vtkIdType SMESH_VisualObj::GetNodeObjId( int theVTKID ) +{ + return myVTK2SMDSNodes.find(theVTKID) == myVTK2SMDSNodes.end() ? -1 : myVTK2SMDSNodes[theVTKID]; +} + +vtkIdType SMESH_VisualObj::GetNodeVTKId( int theObjID ) +{ + return mySMDS2VTKNodes.find(theObjID) == mySMDS2VTKNodes.end() ? -1 : mySMDS2VTKNodes[theObjID]; +} + +vtkIdType SMESH_VisualObj::GetElemObjId( int theVTKID ) +{ + return myVTK2SMDSElems.find(theVTKID) == myVTK2SMDSElems.end() ? -1 : myVTK2SMDSElems[theVTKID]; +} + +vtkIdType SMESH_VisualObj::GetElemVTKId( int theObjID ) +{ + return mySMDS2VTKElems.find(theObjID) == mySMDS2VTKElems.end() ? -1 : mySMDS2VTKElems[theObjID]; +} + +//================================================================================= +// function : SMESH_VisualObj::createPoints +// purpose : Create points from nodes +//================================================================================= +void SMESH_VisualObj::createPoints( vtkPoints* thePoints ) +{ + if ( thePoints == 0 ) + return; + + TEntityList aNodes; + vtkIdType nbNodes = GetEntities( SMESH::NODE, aNodes ); + thePoints->SetNumberOfPoints( nbNodes ); + + int nbPoints = 0; + + TEntityList::const_iterator anIter; + for ( anIter = aNodes.begin(); anIter != aNodes.end(); ++anIter ) + { + const SMDS_MeshNode* aNode = ( const SMDS_MeshNode* )(*anIter); + if ( aNode != 0 ) + { + thePoints->SetPoint( nbPoints, aNode->X(), aNode->Y(), aNode->Z() ); + int anId = aNode->GetID(); + mySMDS2VTKNodes.insert( TMapOfIds::value_type( anId, nbPoints ) ); + myVTK2SMDSNodes.insert( TMapOfIds::value_type( nbPoints, anId ) ); + nbPoints++; + } + } + + if ( nbPoints != nbNodes ) + thePoints->SetNumberOfPoints( nbPoints ); +} + +//================================================================================= +// function : buildPrs +// purpose : create VTK cells( fill unstructured grid ) +//================================================================================= +void SMESH_VisualObj::buildPrs() +{ + try + { + mySMDS2VTKNodes.clear(); + myVTK2SMDSNodes.clear(); + mySMDS2VTKElems.clear(); + myVTK2SMDSElems.clear(); + + if ( IsNodePrs() ) + buildNodePrs(); + else + buildElemPrs(); + } + catch( const std::exception& exc ) + { + INFOS("Follow exception was cought:\n\t"<GetNumberOfCells() = "<GetNumberOfCells() ); + if( MYDEBUGWITHFILES ) WriteUnstructuredGrid( myGrid,"/tmp/buildPrs" ); +} + +//================================================================================= +// function : buildNodePrs +// purpose : create VTK cells for nodes +//================================================================================= +void SMESH_VisualObj::buildNodePrs() +{ + vtkPoints* aPoints = vtkPoints::New(); + createPoints( aPoints ); + int nbPoints = aPoints->GetNumberOfPoints(); + myGrid->SetPoints( aPoints ); + aPoints->Delete(); + + myGrid->SetCells( 0, 0, 0 ); + + // Create cells + + /*vtkIdList *anIdList = vtkIdList::New(); + anIdList->SetNumberOfIds( 1 ); + + vtkCellArray *aCells = vtkCellArray::New(); + aCells->Allocate( 2 * nbPoints, 0 ); + + vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New(); + aCellTypesArray->SetNumberOfComponents( 1 ); + aCellTypesArray->Allocate( nbPoints ); + + for( vtkIdType aCellId = 0; aCellId < nbPoints; aCellId++ ) + { + anIdList->SetId( 0, aCellId ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_VERTEX ); + } + + vtkIntArray* aCellLocationsArray = vtkIntArray::New(); + aCellLocationsArray->SetNumberOfComponents( 1 ); + aCellLocationsArray->SetNumberOfTuples( nbPoints ); + + aCells->InitTraversal(); + for( vtkIdType i = 0, *pts, npts; aCells->GetNextCell( npts, pts ); i++ ) + aCellLocationsArray->SetValue( i, aCells->GetTraversalLocation( npts ) ); + + myGrid->SetCells( aCellTypesArray, aCellLocationsArray, aCells ); + + aCellLocationsArray->Delete(); + aCellTypesArray->Delete(); + aCells->Delete(); + anIdList->Delete(); */ +} + +//================================================================================= +// function : buildElemPrs +// purpose : Create VTK cells for elements +//================================================================================= +void SMESH_VisualObj::buildElemPrs() +{ + // Create points + + vtkPoints* aPoints = vtkPoints::New(); + createPoints( aPoints ); + myGrid->SetPoints( aPoints ); + aPoints->Delete(); + + if ( MYDEBUG ) + MESSAGE("Update - myGrid->GetNumberOfPoints() = "<GetNumberOfPoints()); + + // Calculate cells size + + static SMESH::ElementType aTypes[ 3 ] = { SMESH::EDGE, SMESH::FACE, SMESH::VOLUME }; + + // get entity data + map< int, int > nbEnts; + map< int, TEntityList > anEnts; + + for ( int i = 0; i <= 2; i++ ) + nbEnts[ aTypes[ i ] ] = GetEntities( aTypes[ i ], anEnts[ aTypes[ i ] ] ); + + vtkIdType aCellsSize = 3 * nbEnts[ SMESH::EDGE ]; + + for ( int i = 1; i <= 2; i++ ) // iterate through faces and volumes + { + if ( nbEnts[ aTypes[ i ] ] ) + { + const TEntityList& aList = anEnts[ aTypes[ i ] ]; + TEntityList::const_iterator anIter; + for ( anIter = aList.begin(); anIter != aList.end(); ++anIter ) + aCellsSize += (*anIter)->NbNodes() + 1; + } + } + + vtkIdType aNbCells = nbEnts[ SMESH::EDGE ] + nbEnts[ SMESH::FACE ] + nbEnts[ SMESH::VOLUME ]; + + if ( MYDEBUG ) + MESSAGE( "Update - aNbCells = "<_is_nil() = "<_is_nil()); + + myMeshServer = SMESH::SMESH_Mesh::_duplicate( theMesh ); + myMeshServer->Register(); + myMesh = new SMDS_Mesh(); +} + +//================================================================================= +// function : ~SMESH_MeshObj +// purpose : Destructor +//================================================================================= +SMESH_MeshObj::~SMESH_MeshObj() +{ + myMeshServer->Destroy(); + delete myMesh; +} + +//================================================================================= +// function : Update +// purpose : Update mesh and fill grid with new values if necessary +//================================================================================= +void SMESH_MeshObj::Update( int theIsClear ) +{ + // Update SMDS_Mesh on client part + + try + { + SMESH::log_array_var aSeq = myMeshServer->GetLog( theIsClear ); + CORBA::Long aLength = aSeq->length(); + + if( MYDEBUG ) MESSAGE( "Update: length of the script is "<RemoveNode( FindNode( myMesh, anIndexes[anElemId] ) ); + break; + + case SMESH::REMOVE_ELEMENT: + for( ; anElemId < aNbElems; anElemId++ ) + myMesh->RemoveElement( FindElement( myMesh, anIndexes[anElemId] ) ); + break; + } + } + } + catch ( SALOME::SALOME_Exception& exc ) + { + INFOS("Follow exception was cought:\n\t"<NbNodes() = "<NbNodes()); + MESSAGE("Update - myMesh->NbEdges() = "<NbEdges()); + MESSAGE("Update - myMesh->NbFaces() = "<NbFaces()); + MESSAGE("Update - myMesh->NbVolumes() = "<NbVolumes()); + } + + // Fill unstructured grid + buildPrs(); +} + +//================================================================================= +// function : GetElemDimension +// purpose : Get dimension of element +//================================================================================= +int SMESH_MeshObj::GetElemDimension( const int theObjId ) +{ + const SMDS_MeshElement* anElem = myMesh->FindElement( theObjId ); + if ( anElem == 0 ) + return 0; + + int aType = anElem->GetType(); + switch ( aType ) + { + case SMDSAbs_Edge : return 1; + case SMDSAbs_Face : return 2; + case SMDSAbs_Volume: return 3; + default : return 0; + } +} + +//================================================================================= +// function : GetEntities +// purpose : Get entities of specified type. Return number of entities +//================================================================================= +int SMESH_MeshObj::GetNbEntities( const SMESH::ElementType theType) const +{ + switch ( theType ) + { + case SMESH::NODE: + { + return myMesh->NbNodes(); + } + break; + case SMESH::EDGE: + { + return myMesh->NbEdges(); + } + break; + case SMESH::FACE: + { + return myMesh->NbFaces(); + } + break; + case SMESH::VOLUME: + { + return myMesh->NbVolumes(); + } + break; + default: + return 0; + break; + } +} + +int SMESH_MeshObj::GetEntities( const SMESH::ElementType theType, TEntityList& theObjs ) const +{ + theObjs.clear(); + + switch ( theType ) + { + case SMESH::NODE: + { + SMDS_NodeIteratorPtr anIter = myMesh->nodesIterator(); + while ( anIter->more() ) theObjs.push_back( anIter->next() ); + } + break; + case SMESH::EDGE: + { + SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator(); + while ( anIter->more() ) theObjs.push_back( anIter->next() ); + } + break; + case SMESH::FACE: + { + SMDS_FaceIteratorPtr anIter = myMesh->facesIterator(); + while ( anIter->more() ) theObjs.push_back( anIter->next() ); + } + break; + case SMESH::VOLUME: + { + SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator(); + while ( anIter->more() ) theObjs.push_back( anIter->next() ); + } + break; + default: + break; + } + + return theObjs.size(); +} + +//================================================================================= +// function : UpdateFunctor +// purpose : Update functor in accordance with current mesh +//================================================================================= +void SMESH_MeshObj::UpdateFunctor( SMESH::Functor_ptr f ) +{ + f->SetMesh( myMeshServer ); +} + +//================================================================================= +// function : IsNodePrs +// purpose : Return true if node presentation is used +//================================================================================= +bool SMESH_MeshObj::IsNodePrs() const +{ + return myMesh->NbEdges() == 0 &&myMesh->NbFaces() == 0 &&myMesh->NbVolumes() == 0 ; +} + + +/* + Class : SMESH_SubMeshObj + Description : Base class for visualisation of submeshes and groups +*/ + +//================================================================================= +// function : SMESH_SubMeshObj +// purpose : Constructor +//================================================================================= +SMESH_SubMeshObj::SMESH_SubMeshObj( SMESH_MeshObj* theMeshObj ) +{ + if ( MYDEBUG ) MESSAGE( "SMESH_SubMeshObj - theMeshObj = " << theMeshObj ); + + myMeshObj = theMeshObj; +} + +SMESH_SubMeshObj::~SMESH_SubMeshObj() +{ +} + +//================================================================================= +// function : GetElemDimension +// purpose : Get dimension of element +//================================================================================= +int SMESH_SubMeshObj::GetElemDimension( const int theObjId ) +{ + return myMeshObj == 0 ? 0 : myMeshObj->GetElemDimension( theObjId ); +} + +//================================================================================= +// function : UpdateFunctor +// purpose : Update functor in accordance with current mesh +//================================================================================= +void SMESH_SubMeshObj::UpdateFunctor( SMESH::Functor_ptr f ) +{ + f->SetMesh( myMeshObj->GetMeshServer() ); +} + +//================================================================================= +// function : UpdateFunctor +// purpose : Update mesh object and fill grid with new values +//================================================================================= +void SMESH_SubMeshObj::Update( int theIsClear ) +{ + myMeshObj->Update( theIsClear ); + buildPrs(); +} + + +/* + Class : SMESH_GroupObj + Description : Class for visualisation of groups +*/ + +//================================================================================= +// function : SMESH_GroupObj +// purpose : Constructor +//================================================================================= +SMESH_GroupObj::SMESH_GroupObj( SMESH::SMESH_Group_ptr theGroup, + SMESH_MeshObj* theMeshObj ) +: SMESH_SubMeshObj( theMeshObj ), + myGroupServer( SMESH::SMESH_Group::_duplicate(theGroup) ) +{ + if ( MYDEBUG ) MESSAGE("SMESH_GroupObj - theGroup->_is_nil() = "<_is_nil()); + myGroupServer->Register(); +} + +SMESH_GroupObj::~SMESH_GroupObj() +{ + if ( MYDEBUG ) MESSAGE("~SMESH_GroupObj"); + myGroupServer->Destroy(); +} + +//================================================================================= +// function : IsNodePrs +// purpose : Return true if node presentation is used +//================================================================================= +bool SMESH_GroupObj::IsNodePrs() const +{ + return myGroupServer->GetType() == SMESH::NODE; +} + +//================================================================================= +// function : getNodesFromElems +// purpose : Retrieve nodes from elements +//================================================================================= +static int getNodesFromElems( SMESH::long_array_var& theElemIds, + const SMDS_Mesh* theMesh, + std::list& theResList ) +{ + set aNodeSet; + + for ( CORBA::Long i = 0, n = theElemIds->length(); i < n; i++ ) + { + const SMDS_MeshElement* anElem = theMesh->FindElement( theElemIds[ i ] ); + if ( anElem != 0 ) + { + SMDS_ElemIteratorPtr anIter = anElem->nodesIterator(); + while ( anIter->more() ) + { + const SMDS_MeshElement* aNode = anIter->next(); + if ( aNode != 0 ) + aNodeSet.insert( aNode ); + } + } + } + + set::const_iterator anIter; + for ( anIter = aNodeSet.begin(); anIter != aNodeSet.end(); ++anIter ) + theResList.push_back( *anIter ); + + return theResList.size(); +} + +//================================================================================= +// function : getPointers +// purpose : Get std::list from list of IDs +//================================================================================= +static int getPointers( const SMESH::ElementType theRequestType, + SMESH::long_array_var& theElemIds, + const SMDS_Mesh* theMesh, + std::list& theResList ) +{ + for ( CORBA::Long i = 0, n = theElemIds->length(); i < n; i++ ) + { + const SMDS_MeshElement* anElem = theRequestType == SMESH::NODE + ? theMesh->FindNode( theElemIds[ i ] ) : theMesh->FindElement( theElemIds[ i ] ); + + if ( anElem != 0 ) + theResList.push_back( anElem ); + } + + return theResList.size(); +} + + +//================================================================================= +// function : GetEntities +// purpose : Get entities of specified type. Return number of entities +//================================================================================= +int SMESH_GroupObj::GetNbEntities( const SMESH::ElementType theType) const +{ + if(myGroupServer->GetType() == theType){ + return myGroupServer->Size(); + } + return 0; +} + +int SMESH_GroupObj::GetEntities( const SMESH::ElementType theType, TEntityList& theResList ) const +{ + theResList.clear(); + SMDS_Mesh* aMesh = myMeshObj->GetMesh(); + + if ( myGroupServer->Size() == 0 || aMesh == 0 ) + return 0; + + SMESH::ElementType aGrpType = myGroupServer->GetType(); + SMESH::long_array_var anIds = myGroupServer->GetListOfID(); + + if ( aGrpType == theType ) + return getPointers( theType, anIds, aMesh, theResList ); + else if ( theType == SMESH::NODE ) + return getNodesFromElems( anIds, aMesh, theResList ); + else + return 0; +} + + + +/* + Class : SMESH_subMeshObj + Description : Class for visualisation of submeshes +*/ + +//================================================================================= +// function : SMESH_subMeshObj +// purpose : Constructor +//================================================================================= +SMESH_subMeshObj::SMESH_subMeshObj( SMESH::SMESH_subMesh_ptr theSubMesh, + SMESH_MeshObj* theMeshObj ) +: SMESH_SubMeshObj( theMeshObj ), + mySubMeshServer( SMESH::SMESH_subMesh::_duplicate( theSubMesh ) ) +{ + if ( MYDEBUG ) MESSAGE( "SMESH_subMeshObj - theSubMesh->_is_nil() = " << theSubMesh->_is_nil() ); + + mySubMeshServer->Register(); +} + +SMESH_subMeshObj::~SMESH_subMeshObj() +{ + if ( MYDEBUG ) MESSAGE( "~SMESH_subMeshObj" ); + mySubMeshServer->Destroy(); +} + +//================================================================================= +// function : GetEntities +// purpose : Get entities of specified type. Return number of entities +//================================================================================= +int SMESH_subMeshObj::GetNbEntities( const SMESH::ElementType theType) const +{ + switch ( theType ) + { + case SMESH::NODE: + { + return mySubMeshServer->GetNumberOfNodes(); + } + break; + case SMESH::EDGE: + case SMESH::FACE: + case SMESH::VOLUME: + { + SMESH::long_array_var anIds = mySubMeshServer->GetElementsByType( theType ); + return anIds->length(); + } + default: + return 0; + break; + } +} + +int SMESH_subMeshObj::GetEntities( const SMESH::ElementType theType, TEntityList& theResList ) const +{ + theResList.clear(); + + SMDS_Mesh* aMesh = myMeshObj->GetMesh(); + if ( aMesh == 0 ) + return 0; + + bool isNodal = IsNodePrs(); + + if ( isNodal ) + { + if ( theType == SMESH::NODE ) + { + SMESH::long_array_var anIds = mySubMeshServer->GetNodesId(); + return getPointers( SMESH::NODE, anIds, aMesh, theResList ); + } + } + else + { + if ( theType == SMESH::NODE ) + { + SMESH::long_array_var anIds = mySubMeshServer->GetElementsId(); + return getNodesFromElems( anIds, aMesh, theResList ); + } + else + { + SMESH::long_array_var anIds = mySubMeshServer->GetElementsByType( theType ); + return getPointers( theType, anIds, aMesh, theResList ); + } + } + + return 0; +} + +//================================================================================= +// function : IsNodePrs +// purpose : Return true if node presentation is used +//================================================================================= +bool SMESH_subMeshObj::IsNodePrs() const +{ + return mySubMeshServer->GetNumberOfElements() == 0; +} + + + + + + + + + + + + diff --git a/src/OBJECT/SMESH_Object.h b/src/OBJECT/SMESH_Object.h new file mode 100644 index 000000000..6ed30e2fa --- /dev/null +++ b/src/OBJECT/SMESH_Object.h @@ -0,0 +1,207 @@ +// SMESH OBJECT : interactive object for SMESH visualization +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_Object.h +// Author : Nicolas REJNERI +// Module : SMESH +// $Header$ + +#ifndef SMESH_OBJECT_H +#define SMESH_OBJECT_H + +// IDL Headers +#include +#include CORBA_SERVER_HEADER(SMESH_Mesh) +#include CORBA_SERVER_HEADER(SMESH_Group) +#include CORBA_SERVER_HEADER(SMESH_Filter) + +#include +#include +#include +#include + +class vtkUnstructuredGrid; +class vtkPoints; +class SALOME_ExtractUnstructuredGrid; + +class SMESH_Actor; +class SMDS_Mesh; +class SMDS_MeshNode; +class SMDS_MeshElement; + +class SMESH_VisualObj; +typedef boost::shared_ptr TVisualObjPtr; + + +/* + Class : SMESH_VisualObj + Description : Base class for all mesh objects to be visuilised +*/ + +class SMESH_VisualObj +{ +protected: + + typedef std::list TEntityList; + typedef std::map TMapOfIds; + +public: + SMESH_VisualObj(); + virtual ~SMESH_VisualObj(); + + virtual void Update( int theIsClear = true ) = 0; + virtual void UpdateFunctor( SMESH::Functor_ptr theFunctor ) = 0; + virtual int GetElemDimension( const int theObjId ) = 0; + + virtual int GetNbEntities( const SMESH::ElementType) const = 0; + virtual int GetEntities( const SMESH::ElementType, TEntityList& ) const = 0; + virtual bool IsNodePrs() const = 0; + + vtkUnstructuredGrid* GetUnstructuredGrid() { return myGrid; } + + vtkIdType GetNodeObjId( int theVTKID ); + vtkIdType GetNodeVTKId( int theObjID ); + vtkIdType GetElemObjId( int theVTKID ); + vtkIdType GetElemVTKId( int theObjID ); + +protected: + + void createPoints( vtkPoints* ); + void buildPrs(); + void buildNodePrs(); + void buildElemPrs(); + +private: + + TMapOfIds mySMDS2VTKNodes; + TMapOfIds myVTK2SMDSNodes; + TMapOfIds mySMDS2VTKElems; + TMapOfIds myVTK2SMDSElems; + + vtkUnstructuredGrid* myGrid; +}; + + +/* + Class : SMESH_MeshObj + Description : Class for visualisation of mesh +*/ + +class SMESH_MeshObj: public SMESH_VisualObj +{ +public: + + SMESH_MeshObj( SMESH::SMESH_Mesh_ptr ); + virtual ~SMESH_MeshObj(); + + virtual void Update( int theIsClear = true ); + + virtual int GetNbEntities( const SMESH::ElementType) const; + virtual int GetEntities( const SMESH::ElementType, TEntityList& ) const; + virtual bool IsNodePrs() const; + + virtual int GetElemDimension( const int theObjId ); + + virtual void UpdateFunctor( SMESH::Functor_ptr f ); + + SMESH::SMESH_Mesh_ptr GetMeshServer() { return myMeshServer.in(); } + SMDS_Mesh* GetMesh() { return myMesh; } + +protected: + + SMESH::SMESH_Mesh_var myMeshServer; + SMDS_Mesh* myMesh; +}; + + +/* + Class : SMESH_SubMeshObj + Description : Base class for visualisation of submeshes and groups +*/ + +class SMESH_SubMeshObj: public SMESH_VisualObj +{ +public: + + SMESH_SubMeshObj(SMESH_MeshObj* theMeshObj); + virtual ~SMESH_SubMeshObj(); + + virtual void Update( int theIsClear = true ); + + virtual void UpdateFunctor( SMESH::Functor_ptr ); + virtual int GetElemDimension( const int theObjId ); + +protected: + + SMESH_MeshObj* myMeshObj; +}; + + +/* + Class : SMESH_GroupObj + Description : Class for visualisation of groups +*/ + +class SMESH_GroupObj: public SMESH_SubMeshObj +{ +public: + SMESH_GroupObj( SMESH::SMESH_Group_ptr, SMESH_MeshObj* ); + virtual ~SMESH_GroupObj(); + + virtual int GetNbEntities( const SMESH::ElementType) const; + virtual int GetEntities( const SMESH::ElementType, TEntityList& ) const; + virtual bool IsNodePrs() const; + +private: + + SMESH::SMESH_Group_var myGroupServer; +}; + + +/* + Class : SMESH_subMeshObj + Description : Class for visualisation of submeshes +*/ + +class SMESH_subMeshObj : public SMESH_SubMeshObj +{ +public: + + SMESH_subMeshObj( SMESH::SMESH_subMesh_ptr, + SMESH_MeshObj* ); + virtual ~SMESH_subMeshObj(); + + virtual int GetNbEntities( const SMESH::ElementType) const; + virtual int GetEntities( const SMESH::ElementType, TEntityList& ) const; + virtual bool IsNodePrs() const; + +protected: + + SMESH::SMESH_subMesh_var mySubMeshServer; +}; + + +extern void WriteUnstructuredGrid(vtkUnstructuredGrid* theGrid, const char* theFileName); + + +#endif diff --git a/src/SMDS/Makefile.in b/src/SMDS/Makefile.in index 5c3e9abd9..20bf98ce4 100644 --- a/src/SMDS/Makefile.in +++ b/src/SMDS/Makefile.in @@ -123,7 +123,7 @@ EXPORT_HEADERS= \ #SMDS_MeshNodeIDFactory.hxx # additionnal information to compil and link file -CPPFLAGS += -I${KERNEL_ROOT_DIR}/include/salome +CPPFLAGS += -I${KERNEL_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS) CXXFLAGS += -I${KERNEL_ROOT_DIR}/include/salome LDFLAGS += -L${KERNEL_ROOT_DIR}/lib/salome diff --git a/src/SMDS/SMDS_EdgePosition.hxx b/src/SMDS/SMDS_EdgePosition.hxx index 868310b51..84916246b 100644 --- a/src/SMDS/SMDS_EdgePosition.hxx +++ b/src/SMDS/SMDS_EdgePosition.hxx @@ -38,7 +38,6 @@ class SMDS_EdgePosition:public SMDS_Position SMDS_TypeOfPosition GetTypeOfPosition() const; void SetUParameter(double aUparam); double GetUParameter() const; - ~SMDS_EdgePosition(); private: diff --git a/src/SMDS/SMDS_FaceOfEdges.cxx b/src/SMDS/SMDS_FaceOfEdges.cxx index 0e9243d3f..0a53bba6e 100644 --- a/src/SMDS/SMDS_FaceOfEdges.cxx +++ b/src/SMDS/SMDS_FaceOfEdges.cxx @@ -55,39 +55,44 @@ SMDSAbs_ElementType SMDS_FaceOfEdges::GetType() const return SMDSAbs_Face; } -SMDS_Iterator * SMDS_FaceOfEdges:: +class SMDS_FaceOfEdges_MyIterator:public SMDS_ElemIterator +{ + const vector& mySet; + int index; + public: + SMDS_FaceOfEdges_MyIterator(const vector& s): + mySet(s),index(0) {} + + bool more() + { + return index - { - const vector& mySet; - int index; - public: - MyIterator(const vector& s):mySet(s),index(0) - {} - - bool more() - { - return index set1,set2; - SMDS_Iterator * it; + SMDS_ElemIteratorPtr it; const SMDS_MeshNode * n; it=f1.nodesIterator(); diff --git a/src/SMDS/SMDS_FaceOfEdges.hxx b/src/SMDS/SMDS_FaceOfEdges.hxx index 978ad5df6..414020755 100644 --- a/src/SMDS/SMDS_FaceOfEdges.hxx +++ b/src/SMDS/SMDS_FaceOfEdges.hxx @@ -31,10 +31,13 @@ class SMDS_FaceOfEdges:public SMDS_MeshFace { public: void Print(ostream & OS) const; - SMDS_FaceOfEdges(SMDS_MeshEdge* edge1, SMDS_MeshEdge* edge2, - SMDS_MeshEdge* edge3); - SMDS_FaceOfEdges(SMDS_MeshEdge* edge1, SMDS_MeshEdge* edge2, - SMDS_MeshEdge* edge3, SMDS_MeshEdge* edge4); + SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1, + const SMDS_MeshEdge* edge2, + const SMDS_MeshEdge* edge3); + SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1, + const SMDS_MeshEdge* edge2, + const SMDS_MeshEdge* edge3, + const SMDS_MeshEdge* edge4); SMDSAbs_ElementType GetType() const; int NbEdges() const; @@ -42,7 +45,7 @@ class SMDS_FaceOfEdges:public SMDS_MeshFace // friend bool operator<(const SMDS_FaceOfEdges& e1, const SMDS_FaceOfEdges& e2); protected: - SMDS_Iterator * + SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; private: diff --git a/src/SMDS/SMDS_FaceOfNodes.cxx b/src/SMDS/SMDS_FaceOfNodes.cxx index 9a9a945f9..abc9c9d60 100644 --- a/src/SMDS/SMDS_FaceOfNodes.cxx +++ b/src/SMDS/SMDS_FaceOfNodes.cxx @@ -56,42 +56,47 @@ void SMDS_FaceOfNodes::Print(ostream & OS) const OS << myNodes[i] << ") " << endl; } -SMDS_Iterator * SMDS_FaceOfNodes:: +class SMDS_FaceOfNodes_MyIterator:public SMDS_ElemIterator +{ + const vector& mySet; + int index; + public: + SMDS_FaceOfNodes_MyIterator(const vector& s): + mySet(s),index(0) {} + + bool more() + { + return index - { - const vector& mySet; - int index; - public: - MyIterator(const vector& s):mySet(s),index(0) - {} - - bool more() - { - return index set1,set2; - SMDS_Iterator * it; + SMDS_ElemIteratorPtr it; const SMDS_MeshNode * n; it=f1.nodesIterator(); diff --git a/src/SMDS/SMDS_FaceOfNodes.hxx b/src/SMDS/SMDS_FaceOfNodes.hxx index 809ee5f1c..9a2adad0b 100644 --- a/src/SMDS/SMDS_FaceOfNodes.hxx +++ b/src/SMDS/SMDS_FaceOfNodes.hxx @@ -31,16 +31,19 @@ class SMDS_FaceOfNodes:public SMDS_MeshFace { public: void Print(ostream & OS) const; - SMDS_FaceOfNodes(SMDS_MeshNode* node1, SMDS_MeshNode* node2, - SMDS_MeshNode* node3); - SMDS_FaceOfNodes(SMDS_MeshNode* node1, SMDS_MeshNode* node2, - SMDS_MeshNode* node3, SMDS_MeshNode* node4); + SMDS_FaceOfNodes(const SMDS_MeshNode* node1, + const SMDS_MeshNode* node2, + const SMDS_MeshNode* node3); + SMDS_FaceOfNodes(const SMDS_MeshNode* node1, + const SMDS_MeshNode* node2, + const SMDS_MeshNode* node3, + const SMDS_MeshNode* node4); int NbEdges() const; int NbFaces() const; int NbNodes() const; protected: - SMDS_Iterator * + SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; private: diff --git a/src/SMDS/SMDS_HexahedronOfNodes.cxx b/src/SMDS/SMDS_HexahedronOfNodes.cxx index cebd29a11..8682ad770 100644 --- a/src/SMDS/SMDS_HexahedronOfNodes.cxx +++ b/src/SMDS/SMDS_HexahedronOfNodes.cxx @@ -29,14 +29,14 @@ /// 5,1 and 7,3 are an edges. /////////////////////////////////////////////////////////////////////////////// SMDS_HexahedronOfNodes::SMDS_HexahedronOfNodes( - SMDS_MeshNode * node1, - SMDS_MeshNode * node2, - SMDS_MeshNode * node3, - SMDS_MeshNode * node4, - SMDS_MeshNode * node5, - SMDS_MeshNode * node6, - SMDS_MeshNode * node7, - SMDS_MeshNode * node8) + const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4, + const SMDS_MeshNode * node5, + const SMDS_MeshNode * node6, + const SMDS_MeshNode * node7, + const SMDS_MeshNode * node8) { myNodes[0]=node1; myNodes[1]=node2; @@ -75,18 +75,18 @@ int SMDS_HexahedronOfNodes::NbEdges() const return 12; } -SMDS_Iterator * SMDS_HexahedronOfNodes:: +SMDS_ElemIteratorPtr SMDS_HexahedronOfNodes:: elementsIterator(SMDSAbs_ElementType type) const { - switch(type) - { - case SMDSAbs_Volume: - return SMDS_MeshElement::elementsIterator(SMDSAbs_Volume); - case SMDSAbs_Node: - return new SMDS_IteratorOfArray(myNodes); - default: MESSAGE("ERROR : Iterator not implemented"); - } + switch(type) + { + case SMDSAbs_Volume: + return SMDS_MeshElement::elementsIterator(SMDSAbs_Volume); + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr (new SMDS_IteratorOfArray(myNodes)); + default: MESSAGE("ERROR : Iterator not implemented"); + } } SMDSAbs_ElementType SMDS_HexahedronOfNodes::GetType() const diff --git a/src/SMDS/SMDS_HexahedronOfNodes.hxx b/src/SMDS/SMDS_HexahedronOfNodes.hxx index 2e3f22f4a..03cb242e2 100644 --- a/src/SMDS/SMDS_HexahedronOfNodes.hxx +++ b/src/SMDS/SMDS_HexahedronOfNodes.hxx @@ -36,14 +36,14 @@ class SMDS_HexahedronOfNodes:public SMDS_MeshVolume public: SMDS_HexahedronOfNodes( - SMDS_MeshNode * node1, - SMDS_MeshNode * node2, - SMDS_MeshNode * node3, - SMDS_MeshNode * node4, - SMDS_MeshNode * node5, - SMDS_MeshNode * node6, - SMDS_MeshNode * node7, - SMDS_MeshNode * node8); + const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4, + const SMDS_MeshNode * node5, + const SMDS_MeshNode * node6, + const SMDS_MeshNode * node7, + const SMDS_MeshNode * node8); void Print(ostream & OS) const; int NbFaces() const; @@ -51,7 +51,7 @@ class SMDS_HexahedronOfNodes:public SMDS_MeshVolume int NbEdges() const; SMDSAbs_ElementType GetType() const; protected: - SMDS_Iterator * + SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; const SMDS_MeshNode * myNodes[8]; }; diff --git a/src/SMDS/SMDS_Iterator.hxx b/src/SMDS/SMDS_Iterator.hxx index 144f075d1..264438c7d 100644 --- a/src/SMDS/SMDS_Iterator.hxx +++ b/src/SMDS/SMDS_Iterator.hxx @@ -36,7 +36,11 @@ template class SMDS_Iterator virtual VALUE next()=0; /// Delete the current element and step to the next one - virtual void remove(){}; + virtual void remove(){} + + /// Provide virtual destructor just for case if some derived iterator + /// must have a destructor + virtual ~SMDS_Iterator(){} }; #endif diff --git a/src/SMDS/SMDS_IteratorOfElements.cxx b/src/SMDS/SMDS_IteratorOfElements.cxx index 3f1a392fd..c18f24d25 100644 --- a/src/SMDS/SMDS_IteratorOfElements.cxx +++ b/src/SMDS/SMDS_IteratorOfElements.cxx @@ -27,7 +27,6 @@ bool SMDS_IteratorOfElements::subMore() { if(t1Iterator->more()) { - if(t2Iterator!=NULL) delete t2Iterator; t2Iterator=t1Iterator->next()->elementsIterator(myType); return subMore(); } @@ -39,13 +38,8 @@ bool SMDS_IteratorOfElements::subMore() const SMDS_MeshElement * SMDS_IteratorOfElements::subNext() { if((t2Iterator==NULL)||(!t2Iterator->more())) - { if(t1Iterator->more()) - { - if(t2Iterator!=NULL) delete t2Iterator; t2Iterator=t1Iterator->next()->elementsIterator(myType); - } - } return t2Iterator->next(); } @@ -54,9 +48,12 @@ const SMDS_MeshElement * SMDS_IteratorOfElements::subNext() /// to the element element. it is the iterator to get connectivity of element ////////////////////////////////////////////////////////////////////////////// SMDS_IteratorOfElements::SMDS_IteratorOfElements(const SMDS_MeshElement * element, - SMDSAbs_ElementType type, SMDS_Iterator* it) - :t1Iterator(it), t2Iterator(NULL), myType(type), myElement(element), - myProxyElement(NULL) + SMDSAbs_ElementType type, + const SMDS_ElemIteratorPtr& it) + : t1Iterator(it), + t2Iterator(SMDS_ElemIteratorPtr((SMDS_ElemIterator*)NULL)), + myType(type), myElement(element), + myProxyElement(NULL) { while(subMore()) alreadyReturnedElements.insert(subNext()); @@ -81,7 +78,7 @@ bool SMDS_IteratorOfElements::more() if(myReverseIteration) { - SMDS_Iterator * it= + SMDS_ElemIteratorPtr it= myProxyElement->elementsIterator(myElement->GetType()); while(it->more()) { @@ -103,9 +100,3 @@ const SMDS_MeshElement * SMDS_IteratorOfElements::next() myProxyElement=NULL; return e; } - -SMDS_IteratorOfElements::~SMDS_IteratorOfElements() -{ - delete t1Iterator; - if(t2Iterator!=NULL) delete t2Iterator; -} diff --git a/src/SMDS/SMDS_IteratorOfElements.hxx b/src/SMDS/SMDS_IteratorOfElements.hxx index 5d2d3700c..bb4d94ebe 100644 --- a/src/SMDS/SMDS_IteratorOfElements.hxx +++ b/src/SMDS/SMDS_IteratorOfElements.hxx @@ -25,7 +25,7 @@ using namespace std; -class SMDS_IteratorOfElements:public SMDS_Iterator +class SMDS_IteratorOfElements:public SMDS_ElemIterator { public: ///////////////////////////////////////////////////////////////////////////// @@ -33,14 +33,14 @@ class SMDS_IteratorOfElements:public SMDS_Iterator /// to the element element. it is the iterator to get connectivity of element ////////////////////////////////////////////////////////////////////////////// SMDS_IteratorOfElements(const SMDS_MeshElement * element, - SMDSAbs_ElementType type, SMDS_Iterator* it); + SMDSAbs_ElementType type, + const SMDS_ElemIteratorPtr& it); bool more(); const SMDS_MeshElement * next(); - ~SMDS_IteratorOfElements(); private: - SMDS_Iterator * t2Iterator; - SMDS_Iterator * t1Iterator; + SMDS_ElemIteratorPtr t2Iterator; + SMDS_ElemIteratorPtr t1Iterator; SMDSAbs_ElementType myType; const SMDS_MeshElement * myProxyElement; const SMDS_MeshElement * myElement; diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx index eda54c971..93c4cf568 100644 --- a/src/SMDS/SMDS_Mesh.cxx +++ b/src/SMDS/SMDS_Mesh.cxx @@ -74,7 +74,7 @@ SMDS_Mesh *SMDS_Mesh::AddSubMesh() SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z) { - return AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID()); + return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID()); } /////////////////////////////////////////////////////////////////////////////// @@ -84,18 +84,15 @@ SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z) /////////////////////////////////////////////////////////////////////////////// SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID) { - // find the MeshNode corresponding to ID - const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID); - - if (node == NULL) - { - SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z); - myNodes.insert(node); - myNodeIDFactory->BindID(ID,node); - return node; - } - else - return NULL; + // find the MeshNode corresponding to ID + const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID); + if(!node){ + SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z); + myNodes.insert(node); + myNodeIDFactory->BindID(ID,node); + return node; + }else + return NULL; } /////////////////////////////////////////////////////////////////////////////// @@ -105,10 +102,10 @@ SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID) SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID) { - SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); - SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); - if((node1==NULL)||(node2==NULL)) return NULL; - return AddEdgeWithID(node1, node2, ID); + SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); + SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); + if(!node1 || !node2) return NULL; + return SMDS_Mesh::AddEdgeWithID(node1, node2, ID); } /////////////////////////////////////////////////////////////////////////////// @@ -117,9 +114,9 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID) /////////////////////////////////////////////////////////////////////////////// SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2) + const SMDS_MeshNode * node2) { - return AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID()); + return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID()); } /////////////////////////////////////////////////////////////////////////////// @@ -127,30 +124,28 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1, /// @param idnode1 ID of the first node /// @param idnode2 ID of the second node /// @param ID ID of the edge to create -/// @return The created edge or NULL if an edge with this ID already exists or +/// @return The created edge or NULL if an element with this ID already exists or /// if input nodes are not found. /////////////////////////////////////////////////////////////////////////////// SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, int ID) -{ - SMDS_MeshNode *node1,*node2; - node1=const_cast(n1); - node2=const_cast(n2); - - SMDS_MeshEdge * edge=new SMDS_MeshEdge(node1,node2); - if(myElementIDFactory->BindID(ID, edge)) - { - node1->AddInverseElement(edge); - node2->AddInverseElement(edge); - myEdges.insert(edge); - return edge; - } - else - { - delete edge; - return NULL; - } + const SMDS_MeshNode * n2, + int ID) +{ + SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2); + if(myElementIDFactory->BindID(ID, edge)) { + SMDS_MeshNode *node1,*node2; + node1=const_cast(n1); + node2=const_cast(n2); + node1->AddInverseElement(edge); + node2->AddInverseElement(edge); + myEdges.insert(edge); + return edge; + } + else { + delete edge; + return NULL; + } } /////////////////////////////////////////////////////////////////////////////// @@ -159,81 +154,73 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, /////////////////////////////////////////////////////////////////////////////// SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3) { - return AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID()); + return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID()); } /////////////////////////////////////////////////////////////////////////////// -/// Add a quadrangle defined by its nodes IDs +/// Add a triangle defined by its nodes IDs /////////////////////////////////////////////////////////////////////////////// SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID) { - SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); - SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); - SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); - if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL; - return AddFaceWithID(node1, node2, node3, ID); + SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); + SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); + SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); + if(!node1 || !node2 || !node3) return NULL; + return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID); } /////////////////////////////////////////////////////////////////////////////// -/// Add a quadrangle defined by its nodes +/// Add a triangle defined by its nodes /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshFace* SMDS_Mesh::AddFaceWithID( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, int ID) +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + int ID) { - SMDS_MeshNode *node1, *node2, *node3; - node1=const_cast(n1), - node2=const_cast(n2), - node3=const_cast(n3); - SMDS_MeshFace * face=createTriangle(node1, node2, node3); + SMDS_MeshFace * face=createTriangle(n1, n2, n3); - if(myElementIDFactory->BindID(ID, face)) - { - node1->AddInverseElement(face); - node2->AddInverseElement(face); - node3->AddInverseElement(face); - return face; - } - else - { - RemoveFace(face); - return NULL; - } + if (!registerElement(ID, face)) { + RemoveElement(face, false); + face = NULL; + } + return face; } /////////////////////////////////////////////////////////////////////////////// -/// Add a triangle defined by its nodes. An ID is automatically affected to the +/// Add a quadrangle defined by its nodes. An ID is automatically affected to the /// created face /////////////////////////////////////////////////////////////////////////////// SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4) { - return AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID()); + return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID()); } /////////////////////////////////////////////////////////////////////////////// /// Add a quadrangle defined by its nodes IDs /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, - int idnode4, int ID) +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, + int idnode2, + int idnode3, + int idnode4, + int ID) { - SMDS_MeshNode *node1, *node2, *node3, *node4; - node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); - node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); - node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); - node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); - if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL; - return AddFaceWithID(node1, node2, node3, node4, ID); + SMDS_MeshNode *node1, *node2, *node3, *node4; + node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); + node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); + node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); + node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); + if(!node1 || !node2 || !node3 || !node4) return NULL; + return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID); } /////////////////////////////////////////////////////////////////////////////// @@ -241,29 +228,91 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, /////////////////////////////////////////////////////////////////////////////// SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, int ID) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + int ID) { - SMDS_MeshNode *node1, *node2, *node3, *node4; - node1=const_cast(n1), - node2=const_cast(n2), - node3=const_cast(n3); - node4=const_cast(n4); - SMDS_MeshFace * face=createQuadrangle(node1, node2, node3, node4); + SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4); - if(myElementIDFactory->BindID(ID, face)) - { - node1->AddInverseElement(face); - node2->AddInverseElement(face); - node3->AddInverseElement(face); - node4->AddInverseElement(face); - return face; - } - else - { - RemoveFace(face); - return NULL; - } + if (!registerElement(ID, face)) { + RemoveElement(face, false); + face = NULL; + } + return face; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Add a triangle defined by its edges. An ID is automatically assigned to the +/// Created face +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1, + const SMDS_MeshEdge * e2, + const SMDS_MeshEdge * e3) +{ + if (!hasConstructionEdges()) + return NULL; + return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Add a triangle defined by its edges +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1, + const SMDS_MeshEdge * e2, + const SMDS_MeshEdge * e3, + int ID) +{ + if (!hasConstructionEdges()) + return NULL; + SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3); + myFaces.insert(face); + + if (!registerElement(ID, face)) { + RemoveElement(face, false); + face = NULL; + } + return face; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Add a quadrangle defined by its edges. An ID is automatically assigned to the +/// Created face +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1, + const SMDS_MeshEdge * e2, + const SMDS_MeshEdge * e3, + const SMDS_MeshEdge * e4) +{ + if (!hasConstructionEdges()) + return NULL; + return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Add a quadrangle defined by its edges +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1, + const SMDS_MeshEdge * e2, + const SMDS_MeshEdge * e3, + const SMDS_MeshEdge * e4, + int ID) +{ + if (!hasConstructionEdges()) + return NULL; + SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4); + myFaces.insert(face); + + if (!registerElement(ID, face)) + { + RemoveElement(face, false); + face = NULL; + } + return face; } /////////////////////////////////////////////////////////////////////////////// @@ -272,32 +321,36 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4) { - int ID = myElementIDFactory->GetFreeID(); - SMDS_MeshVolume * v = AddVolumeWithID(n1, n2, n3, n4, ID); - if(v==NULL) myElementIDFactory->ReleaseID(ID); - return v; + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; } /////////////////////////////////////////////////////////////////////////////// ///Create a new tetrahedron and add it to the mesh. ///@param ID The ID of the new volume -///@return The created tetrahedron or NULL if an edge with this ID already exists +///@return The created tetrahedron or NULL if an element with this ID already exists ///or if input nodes are not found. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2, - int idnode3, int idnode4, int ID) +SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, + int idnode2, + int idnode3, + int idnode4, + int ID) { - SMDS_MeshNode *node1, *node2, *node3, *node4; - node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); - node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); - node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); - node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); - if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4=NULL)) return NULL; - return AddVolumeWithID(node1, node2, node3, node4, ID); + SMDS_MeshNode *node1, *node2, *node3, *node4; + node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); + node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); + node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); + node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); + if(!node1 || !node2 || !node3 || !node4) return NULL; + return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID); } /////////////////////////////////////////////////////////////////////////////// @@ -306,51 +359,35 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2, ///@return The created tetrahedron /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, int ID) -{ - SMDS_MeshNode *node1, *node2, *node3, *node4; - node1=const_cast(n1), - node2=const_cast(n2), - node3=const_cast(n3); - node4=const_cast(n4); - SMDS_MeshVolume* volume; - if(hasConstructionFaces()) - { - SMDS_MeshFace * f1=createTriangle(node1,node2,node3); - SMDS_MeshFace * f2=createTriangle(node1,node2,node4); - SMDS_MeshFace * f3=createTriangle(node1,node3,node4); - SMDS_MeshFace * f4=createTriangle(node2,node3,node4); - volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4); - myVolumes.insert(volume); - } - else if(hasConstructionEdges()) - { - MESSAGE("Error : Not implemented"); - return NULL; - } - else - { - volume=new SMDS_VolumeOfNodes(node1,node2,node3,node4); - myVolumes.insert(volume); - } - - if(myElementIDFactory->BindID(ID, volume)) - { - node1->AddInverseElement(volume); - node2->AddInverseElement(volume); - node3->AddInverseElement(volume); - node4->AddInverseElement(volume); - return volume; - } - else - { - RemoveVolume(volume); - return NULL; - } +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + int ID) +{ + SMDS_MeshVolume* volume; + if(hasConstructionFaces()) { + SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3); + SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4); + SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4); + SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4); + volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4); + myVolumes.insert(volume); + } + else if(hasConstructionEdges()) { + MESSAGE("Error : Not implemented"); + return NULL; + } + else { + volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4); + myVolumes.insert(volume); + } + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; } /////////////////////////////////////////////////////////////////////////////// @@ -360,36 +397,40 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID( /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, const SMDS_MeshNode * n5) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5) { - int ID = myElementIDFactory->GetFreeID(); - SMDS_MeshVolume * v = AddVolumeWithID(n1, n2, n3, n4, n5, ID); - if(v==NULL) myElementIDFactory->ReleaseID(ID); - return v; + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; } /////////////////////////////////////////////////////////////////////////////// ///Create a new pyramid and add it to the mesh. ///Nodes 1,2,3 and 4 define the base of the pyramid ///@param ID The ID of the new volume -///@return The created pyramid or NULL if a pyramid with this ID already exists +///@return The created pyramid or NULL if an element with this ID already exists ///or if input nodes are not found. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2, - int idnode3, int idnode4, int idnode5, int ID) +SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, + int idnode2, + int idnode3, + int idnode4, + int idnode5, + int ID) { - SMDS_MeshNode *node1, *node2, *node3, *node4, *node5; - node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); - node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); - node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); - node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); - node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5); - if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4=NULL)|| - (node5=NULL)) - return NULL; - return AddVolumeWithID(node1, node2, node3, node4, node5, ID); + SMDS_MeshNode *node1, *node2, *node3, *node4, *node5; + node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); + node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); + node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); + node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); + node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5); + if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL; + return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID); } /////////////////////////////////////////////////////////////////////////////// @@ -399,54 +440,36 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2, ///@return The created pyramid /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, int ID) -{ - SMDS_MeshNode *node1, *node2, *node3, *node4, *node5; - node1=const_cast(n1), - node2=const_cast(n2), - node3=const_cast(n3); - node4=const_cast(n4); - node5=const_cast(n5); - SMDS_MeshVolume* volume; - if(hasConstructionFaces()) - { - SMDS_MeshFace * f1=createQuadrangle(node1,node2,node3,node4); - SMDS_MeshFace * f2=createTriangle(node1,node2,node5); - SMDS_MeshFace * f3=createTriangle(node2,node3,node5); - SMDS_MeshFace * f4=createTriangle(node3,node4,node5); - volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4); - myVolumes.insert(volume); - } - else if(hasConstructionEdges()) - { - MESSAGE("Error : Not implemented"); - return NULL; - } - else - { - volume=new SMDS_VolumeOfNodes(node1,node2,node3,node4,node5); - myVolumes.insert(volume); - } - - if(myElementIDFactory->BindID(ID, volume)) - { - node1->AddInverseElement(volume); - node2->AddInverseElement(volume); - node3->AddInverseElement(volume); - node4->AddInverseElement(volume); - node5->AddInverseElement(volume); - return volume; - } - else - { - RemoveVolume(volume); - return NULL; - } +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + int ID) +{ + SMDS_MeshVolume* volume; + if(hasConstructionFaces()) { + SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4); + SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5); + SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5); + SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5); + volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4); + myVolumes.insert(volume); + } + else if(hasConstructionEdges()) { + MESSAGE("Error : Not implemented"); + return NULL; + } + else { + volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5); + myVolumes.insert(volume); + } + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; } /////////////////////////////////////////////////////////////////////////////// @@ -456,38 +479,43 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID( /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6) { - int ID = myElementIDFactory->GetFreeID(); - SMDS_MeshVolume * v = AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID); - if(v==NULL) myElementIDFactory->ReleaseID(ID); - return v; + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; } /////////////////////////////////////////////////////////////////////////////// ///Create a new prism and add it to the mesh. ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle. ///@param ID The ID of the new volume -///@return The created prism or NULL if a prism with this ID already exists +///@return The created prism or NULL if an element with this ID already exists ///or if input nodes are not found. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2, - int idnode3, int idnode4, int idnode5, int idnode6, int ID) -{ - SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6; - node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); - node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); - node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); - node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); - node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5); - node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6); - if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4=NULL)|| - (node5==NULL)||(node6=NULL)) - return NULL; - return AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID); +SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, + int idnode2, + int idnode3, + int idnode4, + int idnode5, + int idnode6, + int ID) +{ + SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6; + node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); + node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); + node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); + node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); + node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5); + node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6); + if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL; + return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID); } /////////////////////////////////////////////////////////////////////////////// @@ -497,58 +525,38 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2, ///@return The created prism /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, int ID) -{ - SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6; - node1=const_cast(n1), - node2=const_cast(n2), - node3=const_cast(n3); - node4=const_cast(n4); - node5=const_cast(n5); - node6=const_cast(n6); - SMDS_MeshVolume* volume; - if(hasConstructionFaces()) - { - SMDS_MeshFace * f1=createTriangle(node1,node2,node3); - SMDS_MeshFace * f2=createTriangle(node4,node5,node6); - SMDS_MeshFace * f3=createQuadrangle(node1,node4,node5,node2); - SMDS_MeshFace * f4=createQuadrangle(node2,node5,node6,node3); - SMDS_MeshFace * f5=createQuadrangle(node3,node6,node4,node1); - volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5); - myVolumes.insert(volume); - } - else if(hasConstructionEdges()) - { - MESSAGE("Error : Not implemented"); - return NULL; - } - else - { - volume=new SMDS_VolumeOfNodes(node1,node2,node3,node4,node5,node6); - myVolumes.insert(volume); - } - - if(myElementIDFactory->BindID(ID, volume)) - { - node1->AddInverseElement(volume); - node2->AddInverseElement(volume); - node3->AddInverseElement(volume); - node4->AddInverseElement(volume); - node5->AddInverseElement(volume); - node6->AddInverseElement(volume); - return volume; - } - else - { - RemoveVolume(volume); - return NULL; - } +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + int ID) +{ + SMDS_MeshVolume* volume; + if(hasConstructionFaces()) { + SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3); + SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6); + SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2); + SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3); + SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1); + volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5); + myVolumes.insert(volume); + } + else if(hasConstructionEdges()) { + MESSAGE("Error : Not implemented"); + return NULL; + } + else { + volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6); + myVolumes.insert(volume); + } + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; } /////////////////////////////////////////////////////////////////////////////// @@ -558,113 +566,236 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID( /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8) { - int ID = myElementIDFactory->GetFreeID(); - SMDS_MeshVolume * v = AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID); - if(v==NULL) myElementIDFactory->ReleaseID(ID); - return v; + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; } /////////////////////////////////////////////////////////////////////////////// ///Create a new hexahedron and add it to the mesh. ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges. ///@param ID The ID of the new volume -///@return The created hexahedron or NULL if an hexahedron with this ID already +///@return The created hexahedron or NULL if an element with this ID already ///exists or if input nodes are not found. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2, - int idnode3, int idnode4, int idnode5, int idnode6, int idnode7, - int idnode8, int ID) -{ - SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8; - node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); - node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); - node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); - node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); - node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5); - node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6); - node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7); - node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8); - if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4==NULL)|| - (node5==NULL)||(node6==NULL)||(node7==NULL)||(node8==NULL)) - return NULL; - return AddVolumeWithID(node1, node2, node3, node4, node5, node6, node7, - node8, ID); +SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, + int idnode2, + int idnode3, + int idnode4, + int idnode5, + int idnode6, + int idnode7, + int idnode8, + int ID) +{ + SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8; + node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); + node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); + node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); + node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); + node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5); + node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6); + node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7); + node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8); + if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8) + return NULL; + return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, + node7, node8, ID); } /////////////////////////////////////////////////////////////////////////////// ///Create a new hexahedron and add it to the mesh. ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges. ///@param ID The ID of the new volume -///@return The created prism or NULL if an hexadron with this ID already exists +///@return The created prism or NULL if an element with this ID already exists ///or if input nodes are not found. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, - const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, int ID) -{ - SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8; - node1=const_cast(n1), - node2=const_cast(n2), - node3=const_cast(n3); - node4=const_cast(n4); - node5=const_cast(n5); - node6=const_cast(n6); - node7=const_cast(n7); - node8=const_cast(n8); - SMDS_MeshVolume* volume; - if(hasConstructionFaces()) - { - SMDS_MeshFace * f1=FindFaceOrCreate(node1,node2,node3,node4); - SMDS_MeshFace * f2=FindFaceOrCreate(node5,node6,node7,node8); - SMDS_MeshFace * f3=FindFaceOrCreate(node1,node4,node8,node5); - SMDS_MeshFace * f4=FindFaceOrCreate(node1,node2,node6,node5); - SMDS_MeshFace * f5=FindFaceOrCreate(node2,node3,node7,node6); - SMDS_MeshFace * f6=FindFaceOrCreate(node3,node4,node8,node7); - volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6); - myVolumes.insert(volume); - } - else if(hasConstructionEdges()) - { - MESSAGE("Error : Not implemented"); - return NULL; - } - else - { - volume=new SMDS_HexahedronOfNodes(node1,node2,node3,node4,node5,node6, - node7,node8); - myVolumes.insert(volume); - } +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + int ID) +{ + SMDS_MeshVolume* volume; + if(hasConstructionFaces()) { + SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4); + SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8); + SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5); + SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5); + SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6); + SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7); + volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6); + myVolumes.insert(volume); + } + else if(hasConstructionEdges()) { + MESSAGE("Error : Not implemented"); + return NULL; + } + else { + volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8); + myVolumes.insert(volume); + } + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new tetrahedron defined by its faces and add it to the mesh. +///@return The created tetrahedron +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4) +{ + if (!hasConstructionFaces()) + return NULL; + return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new tetrahedron defined by its faces and add it to the mesh. +///@param ID The ID of the new volume +///@return The created tetrahedron +/////////////////////////////////////////////////////////////////////////////// - if(myElementIDFactory->BindID(ID, volume)) - { - node1->AddInverseElement(volume); - node2->AddInverseElement(volume); - node3->AddInverseElement(volume); - node4->AddInverseElement(volume); - node5->AddInverseElement(volume); - node6->AddInverseElement(volume); - node7->AddInverseElement(volume); - node8->AddInverseElement(volume); - return volume; - } - else - { - RemoveVolume(volume); - return NULL; - } +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + int ID) +{ + if (!hasConstructionFaces()) + return NULL; + SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4); + myVolumes.insert(volume); + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new pyramid defined by its faces and add it to the mesh. +///@return The created pyramid +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + const SMDS_MeshFace * f5) +{ + if (!hasConstructionFaces()) + return NULL; + return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new pyramid defined by its faces and add it to the mesh. +///@param ID The ID of the new volume +///@return The created pyramid +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + const SMDS_MeshFace * f5, + int ID) +{ + if (!hasConstructionFaces()) + return NULL; + SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5); + myVolumes.insert(volume); + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new prism defined by its faces and add it to the mesh. +///@return The created prism +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + const SMDS_MeshFace * f5, + const SMDS_MeshFace * f6) +{ + if (!hasConstructionFaces()) + return NULL; + return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new prism defined by its faces and add it to the mesh. +///@param ID The ID of the new volume +///@return The created prism +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + const SMDS_MeshFace * f5, + const SMDS_MeshFace * f6, + int ID) +{ + if (!hasConstructionFaces()) + return NULL; + SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6); + myVolumes.insert(volume); + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Registers element with the given ID, maintains inverse connections +/////////////////////////////////////////////////////////////////////////////// +bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element) +{ + if (myElementIDFactory->BindID(ID, element)) { + SMDS_ElemIteratorPtr it = element->nodesIterator(); + while (it->more()) { + SMDS_MeshNode *node = static_cast + (const_cast(it->next())); + node->AddInverseElement(element); + } + return true; + } + return false; } /////////////////////////////////////////////////////////////////////////////// @@ -672,15 +803,16 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID( /////////////////////////////////////////////////////////////////////////////// const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const { - return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID); + return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID); } /////////////////////////////////////////////////////////////////////////////// ///Create a triangle and add it to the current mesh. This methode do not bind a ///ID to the create triangle. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshFace * SMDS_Mesh::createTriangle(SMDS_MeshNode * node1, - SMDS_MeshNode * node2, SMDS_MeshNode * node3) +SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3) { if(hasConstructionEdges()) { @@ -705,8 +837,10 @@ SMDS_MeshFace * SMDS_Mesh::createTriangle(SMDS_MeshNode * node1, ///Create a quadrangle and add it to the current mesh. This methode do not bind ///a ID to the create triangle. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshFace * SMDS_Mesh::createQuadrangle(SMDS_MeshNode * node1, - SMDS_MeshNode * node2, SMDS_MeshNode * node3, SMDS_MeshNode * node4) +SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4) { if(hasConstructionEdges()) { @@ -812,9 +946,6 @@ const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const return FindEdge(node1,node2); } -/////////////////////////////////////////////////////////////////////////////// -/// -/////////////////////////////////////////////////////////////////////////////// //#include "Profiler.h" const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2) const @@ -822,14 +953,14 @@ const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1, const SMDS_MeshEdge * toReturn=NULL; //PROFILER_Init(); //PROFILER_Set(); - SMDS_Iterator* it1=node1->edgesIterator(); + SMDS_ElemIteratorPtr it1=node1->edgesIterator(); //PROFILER_Get(0); //PROFILER_Set(); while(it1->more()) { const SMDS_MeshEdge * e=static_cast (it1->next()); - SMDS_Iterator* it2=e->nodesIterator(); + SMDS_ElemIteratorPtr it2=e->nodesIterator(); while(it2->more()) { if(it2->next()->GetID()==node2->GetID()) @@ -838,10 +969,8 @@ const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1, break; } } - delete it2; } //PROFILER_Get(1); - delete it1; return toReturn; } @@ -853,9 +982,8 @@ SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1, toReturn=const_cast(FindEdge(node1,node2)); if(toReturn==NULL) { - toReturn=new SMDS_MeshEdge(const_cast(node1), - const_cast(node2)); - myEdges.insert(toReturn); + toReturn=new SMDS_MeshEdge(node1,node2); + myEdges.insert(toReturn); } return toReturn; } @@ -871,36 +999,53 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, const SMDS_MeshNode * node1=FindNode(idnode1); const SMDS_MeshNode * node2=FindNode(idnode2); const SMDS_MeshNode * node3=FindNode(idnode3); + if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL; + return FindFace(node1, node2, node3); +} + +const SMDS_MeshFace* SMDS_Mesh::FindFace( + const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3) const +{ const SMDS_MeshFace * face; const SMDS_MeshElement * node; bool node2found, node3found; - if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL; - SMDS_Iterator* it1=node1->facesIterator(); + SMDS_ElemIteratorPtr it1=node1->facesIterator(); while(it1->more()) { face=static_cast(it1->next()); if(face->NbNodes()!=3) continue; - SMDS_Iterator* it2=face->nodesIterator(); + SMDS_ElemIteratorPtr it2=face->nodesIterator(); node2found=false; node3found=false; while(it2->more()) { node=it2->next(); - if(node->GetID()==idnode2) node2found=true; - if(node->GetID()==idnode3) node3found=true; + if(node->GetID()==node2->GetID()) node2found=true; + if(node->GetID()==node3->GetID()) node3found=true; } - delete it2; if(node2found&&node3found) - { - delete it1; return face; - } } - delete it1; return NULL; } +SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate( + const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3) +{ + SMDS_MeshFace * toReturn=NULL; + toReturn=const_cast(FindFace(node1,node2,node3)); + if(toReturn==NULL) + { + toReturn=createTriangle(node1,node2,node3); + } + return toReturn; +} + //======================================================================= //function : FindFace //purpose : @@ -926,12 +1071,12 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace( const SMDS_MeshFace * face; const SMDS_MeshElement * node; bool node2found, node3found, node4found; - SMDS_Iterator* it1=node1->facesIterator(); + SMDS_ElemIteratorPtr it1=node1->facesIterator(); while(it1->more()) { face=static_cast(it1->next()); if(face->NbNodes()!=4) continue; - SMDS_Iterator* it2=face->nodesIterator(); + SMDS_ElemIteratorPtr it2=face->nodesIterator(); node2found=false; node3found=false; node4found=false; @@ -942,14 +1087,9 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace( if(node->GetID()==node3->GetID()) node3found=true; if(node->GetID()==node4->GetID()) node4found=true; } - delete it2; if(node2found&&node3found&&node4found) - { - delete it1; return face; - } } - delete it1; return NULL; } @@ -961,15 +1101,10 @@ SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate( { SMDS_MeshFace * toReturn=NULL; toReturn=const_cast(FindFace(node1,node2,node3,node4)); - if(toReturn==NULL) + if(toReturn==NULL) { - toReturn=createQuadrangle( - const_cast(node1), - const_cast(node2), - const_cast(node3), - const_cast(node4) - ); - } + toReturn=createQuadrangle(node1,node2,node3,node4); + } return toReturn; } @@ -991,9 +1126,8 @@ const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const void SMDS_Mesh::DumpNodes() const { MESSAGE("dump nodes of mesh : "); - SMDS_Iterator * itnode=nodesIterator(); + SMDS_NodeIteratorPtr itnode=nodesIterator(); while(itnode->more()) MESSAGE(itnode->next()); - delete itnode; } //======================================================================= @@ -1004,9 +1138,8 @@ void SMDS_Mesh::DumpNodes() const void SMDS_Mesh::DumpEdges() const { MESSAGE("dump edges of mesh : "); - SMDS_Iterator * itedge=edgesIterator(); + SMDS_EdgeIteratorPtr itedge=edgesIterator(); while(itedge->more()) MESSAGE(itedge->next()); - delete itedge; } //======================================================================= @@ -1017,9 +1150,8 @@ void SMDS_Mesh::DumpEdges() const void SMDS_Mesh::DumpFaces() const { MESSAGE("dump faces of mesh : "); - SMDS_Iterator * itface=facesIterator(); + SMDS_FaceIteratorPtr itface=facesIterator(); while(itface->more()) MESSAGE(itface->next()); - delete itface; } //======================================================================= @@ -1030,9 +1162,8 @@ void SMDS_Mesh::DumpFaces() const void SMDS_Mesh::DumpVolumes() const { MESSAGE("dump volumes of mesh : "); - SMDS_Iterator * itvol=volumesIterator(); + SMDS_VolumeIteratorPtr itvol=volumesIterator(); while(itvol->more()) MESSAGE(itvol->next()); - delete itvol; } //======================================================================= @@ -1053,7 +1184,7 @@ void SMDS_Mesh::DebugStats() const //#ifdef DEB - SMDS_Iterator * itnode=nodesIterator(); + SMDS_NodeIteratorPtr itnode=nodesIterator(); int sizeofnodes = 0; int sizeoffaces = 0; @@ -1063,19 +1194,16 @@ void SMDS_Mesh::DebugStats() const sizeofnodes += sizeof(*node); - SMDS_Iterator * it= - node->GetInverseElementIterator(); + SMDS_ElemIteratorPtr it = node->GetInverseElementIterator(); while(it->more()) { const SMDS_MeshElement *me = it->next(); sizeofnodes += sizeof(me); } - delete it; } - delete itnode; - SMDS_Iterator* itface=facesIterator(); - + + SMDS_FaceIteratorPtr itface=facesIterator(); while(itface->more()) { const SMDS_MeshElement *face = itface->next(); @@ -1086,7 +1214,6 @@ void SMDS_Mesh::DebugStats() const MESSAGE("total size of face elements = " << sizeoffaces);; //#endif - } /////////////////////////////////////////////////////////////////////////////// @@ -1150,12 +1277,11 @@ SMDS_Mesh::~SMDS_Mesh() itc++; } - SMDS_Iterator * itn=nodesIterator(); + SMDS_NodeIteratorPtr itn=nodesIterator(); while(itn->more()) { delete itn->next(); } - delete itn; set::iterator ite=myEdges.begin(); while(ite!=myEdges.end()) @@ -1177,7 +1303,6 @@ SMDS_Mesh::~SMDS_Mesh() delete *itv; itv++; } - } /////////////////////////////////////////////////////////////////////////////// @@ -1243,143 +1368,151 @@ void SMDS_Mesh::setInverseElements(bool b) /// Return an iterator on nodes of the current mesh. Once used this iterator /// must be free by the caller /////////////////////////////////////////////////////////////////////////////// -SMDS_Iterator * SMDS_Mesh::nodesIterator() const +class SMDS_Mesh_MyNodeIterator:public SMDS_NodeIterator { - class MyIterator:public SMDS_Iterator - { - const SetOfNodes& mySet; - SetOfNodes::iterator myIterator; - public: - MyIterator(const SetOfNodes& s):mySet(s) - { - myIterator=mySet.begin(); - } + typedef SMDS_Mesh::SetOfNodes SetOfNodes; + const SetOfNodes& mySet; + SetOfNodes::iterator myIterator; + public: + SMDS_Mesh_MyNodeIterator(const SetOfNodes& s):mySet(s) + { + myIterator=mySet.begin(); + } - bool more() - { - return myIterator!=mySet.end(); - } + bool more() + { + return myIterator!=mySet.end(); + } - const SMDS_MeshNode* next() - { - const SMDS_MeshNode* current=*myIterator; - myIterator++; - return current; - } - }; - return new MyIterator(myNodes); + const SMDS_MeshNode* next() + { + const SMDS_MeshNode* current=*myIterator; + myIterator++; + return current; + } +}; + +SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const +{ + return SMDS_NodeIteratorPtr(new SMDS_Mesh_MyNodeIterator(myNodes)); } /////////////////////////////////////////////////////////////////////////////// -///Return an iterator on egdes of the current mesh. Once used this iterator +///Return an iterator on volumes of the current mesh. Once used this iterator ///must be free by the caller /////////////////////////////////////////////////////////////////////////////// -SMDS_Iterator * SMDS_Mesh::edgesIterator() const +class SMDS_Mesh_MyEdgeIterator:public SMDS_EdgeIterator { - class MyIterator:public SMDS_Iterator - { - const SetOfEdges& mySet; - const SMDS_MeshEdge * myEdge; - SetOfEdges::iterator myIterator; - public: - MyIterator(const SetOfEdges& s):mySet(s) - { - myIterator=mySet.begin(); - } + typedef SMDS_Mesh::SetOfEdges SetOfEdges; + const SetOfEdges& mySet; + const SMDS_MeshEdge * myEdge; + SetOfEdges::iterator myIterator; + public: + SMDS_Mesh_MyEdgeIterator(const SetOfEdges& s):mySet(s) + { + myIterator=mySet.begin(); + } - bool more() - { - while((myIterator!=mySet.end())) - { - if((*myIterator)->GetID()!=-1) - return true; - myIterator++; - } - return false; - } + bool more() + { + while((myIterator!=mySet.end())) + { + if((*myIterator)->GetID()!=-1) + return true; + myIterator++; + } + return false; + } - const SMDS_MeshEdge* next() - { - const SMDS_MeshEdge* current=*myIterator; - myIterator++; - return current; - } - }; - return new MyIterator(myEdges); + const SMDS_MeshEdge* next() + { + const SMDS_MeshEdge* current=*myIterator; + myIterator++; + return current; + } +}; + +SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const +{ + return SMDS_EdgeIteratorPtr(new SMDS_Mesh_MyEdgeIterator(myEdges)); } /////////////////////////////////////////////////////////////////////////////// ///Return an iterator on faces of the current mesh. Once used this iterator ///must be free by the caller /////////////////////////////////////////////////////////////////////////////// -SMDS_Iterator * SMDS_Mesh::facesIterator() const +class SMDS_Mesh_MyFaceIterator:public SMDS_FaceIterator { - class MyIterator:public SMDS_Iterator - { - const SetOfFaces& mySet; - set::iterator myIterator; - public: - MyIterator(const SetOfFaces& s):mySet(s) - { - myIterator=mySet.begin(); - } + typedef SMDS_Mesh::SetOfFaces SetOfFaces; + const SetOfFaces& mySet; + SetOfFaces::iterator myIterator; + public: + SMDS_Mesh_MyFaceIterator(const SetOfFaces& s):mySet(s) + { + myIterator=mySet.begin(); + } - bool more() - { - while((myIterator!=mySet.end())) - { - if((*myIterator)->GetID()!=-1) - return true; - myIterator++; - } - return false; - } + bool more() + { + while((myIterator!=mySet.end())) + { + if((*myIterator)->GetID()!=-1) + return true; + myIterator++; + } + return false; + } - const SMDS_MeshFace* next() - { - const SMDS_MeshFace* current=*myIterator; - myIterator++; - return current; - } - }; - return new MyIterator(myFaces); + const SMDS_MeshFace* next() + { + const SMDS_MeshFace* current=*myIterator; + myIterator++; + return current; + } +}; + +SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const +{ + return SMDS_FaceIteratorPtr(new SMDS_Mesh_MyFaceIterator(myFaces)); } /////////////////////////////////////////////////////////////////////////////// ///Return an iterator on volumes of the current mesh. Once used this iterator ///must be free by the caller /////////////////////////////////////////////////////////////////////////////// -SMDS_Iterator * SMDS_Mesh::volumesIterator() const +class SMDS_Mesh_MyVolumeIterator:public SMDS_VolumeIterator { - class MyIterator:public SMDS_Iterator - { - const SetOfVolumes& mySet; - SetOfVolumes::iterator myIterator; - public: - MyIterator(const SetOfVolumes& s):mySet(s) - { - myIterator=mySet.begin(); - } + typedef SMDS_Mesh::SetOfVolumes SetOfVolumes; + const SetOfVolumes& mySet; + SetOfVolumes::iterator myIterator; + public: + SMDS_Mesh_MyVolumeIterator(const SetOfVolumes& s):mySet(s) + { + myIterator=mySet.begin(); + } - bool more() - { - return myIterator!=mySet.end(); - } + bool more() + { + return myIterator!=mySet.end(); + } - const SMDS_MeshVolume* next() - { - const SMDS_MeshVolume* current=*myIterator; - myIterator++; - return current; - } - }; - return new MyIterator(myVolumes); + const SMDS_MeshVolume* next() + { + const SMDS_MeshVolume* current=*myIterator; + myIterator++; + return current; + } +}; + +SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const +{ + return SMDS_VolumeIteratorPtr(new SMDS_Mesh_MyVolumeIterator(myVolumes)); } /////////////////////////////////////////////////////////////////////////////// /// Do intersection of sets (more than 2) /////////////////////////////////////////////////////////////////////////////// -set * intersectionOfSets( +static set * intersectionOfSets( set vs[], int numberOfSets) { set* rsetA=new set(vs[0]); @@ -1401,26 +1534,25 @@ set * intersectionOfSets( /////////////////////////////////////////////////////////////////////////////// /// Return the list of finit elements owning the given element /////////////////////////////////////////////////////////////////////////////// -set * getFinitElements(const SMDS_MeshElement * element) +static set * getFinitElements(const SMDS_MeshElement * element) { int numberOfSets=element->NbNodes(); set initSet[numberOfSets]; - SMDS_Iterator * itNodes=element->nodesIterator(); + SMDS_ElemIteratorPtr itNodes=element->nodesIterator(); int i=0; while(itNodes->more()) { const SMDS_MeshNode * n=static_cast(itNodes->next()); - SMDS_Iterator * itFe = n->GetInverseElementIterator(); + SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); //initSet[i]=set(); - while(itFe->more()) initSet[i].insert(itFe->next()); + while(itFe->more()) + initSet[i].insert(itFe->next()); i++; - delete itFe; } - delete itNodes; return intersectionOfSets(initSet, numberOfSets); } @@ -1428,7 +1560,7 @@ set * getFinitElements(const SMDS_MeshElement * element /////////////////////////////////////////////////////////////////////////////// /// Return the list of nodes used only by the given elements /////////////////////////////////////////////////////////////////////////////// -set * getExclusiveNodes( +static set * getExclusiveNodes( set& elements) { set * toReturn=new set(); @@ -1436,20 +1568,18 @@ set * getExclusiveNodes( while(itElements!=elements.end()) { - SMDS_Iterator * itNodes= - (*itElements)->nodesIterator(); + SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator(); itElements++; while(itNodes->more()) { const SMDS_MeshNode * n=static_cast(itNodes->next()); - SMDS_Iterator * itFe = n->GetInverseElementIterator(); + SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); set s; - while(itFe->more()) s.insert(itFe->next()); - delete itFe; + while(itFe->more()) + s.insert(itFe->next()); if(s==elements) toReturn->insert(n); } - delete itNodes; } return toReturn; } @@ -1471,46 +1601,49 @@ void SMDS_Mesh::addChildrenWithNodes(set& setOfChildren break; case SMDSAbs_Edge: { - SMDS_Iterator * itn=element->nodesIterator(); + SMDS_ElemIteratorPtr itn=element->nodesIterator(); while(itn->more()) { const SMDS_MeshElement * e=itn->next(); - if(nodes.find(e)!=nodes.end()) setOfChildren.insert(element); + if(nodes.find(e)!=nodes.end()) + { + setOfChildren.insert(element); + break; + } } - delete itn; - } break; + } break; case SMDSAbs_Face: { - SMDS_Iterator * itn=element->nodesIterator(); + SMDS_ElemIteratorPtr itn=element->nodesIterator(); while(itn->more()) { const SMDS_MeshElement * e=itn->next(); - if(nodes.find(e)!=nodes.end()) setOfChildren.insert(element); + if(nodes.find(e)!=nodes.end()) + { + setOfChildren.insert(element); + break; + } } - delete itn; if(hasConstructionEdges()) { - SMDS_Iterator* ite=element->edgesIterator(); + SMDS_ElemIteratorPtr ite=element->edgesIterator(); while(ite->more()) addChildrenWithNodes(setOfChildren, ite->next(), nodes); - delete ite; } } break; case SMDSAbs_Volume: { if(hasConstructionFaces()) { - SMDS_Iterator * ite=element->facesIterator(); + SMDS_ElemIteratorPtr ite=element->facesIterator(); while(ite->more()) addChildrenWithNodes(setOfChildren, ite->next(), nodes); - delete ite; } else if(hasConstructionEdges()) { - SMDS_Iterator * ite=element->edgesIterator(); + SMDS_ElemIteratorPtr ite=element->edgesIterator(); while(ite->more()) addChildrenWithNodes(setOfChildren, ite->next(), nodes); - delete ite; } } } @@ -1523,177 +1656,135 @@ void SMDS_Mesh::addChildrenWithNodes(set& setOfChildren void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, const bool removenodes) { - set * s1=getFinitElements(elem); - - set * s2=getExclusiveNodes(*s1); - set s3; - set::iterator it=s1->begin(); - while(it!=s1->end()) - { - addChildrenWithNodes(s3, *it ,*s2); - s3.insert(*it); - it++; - } - if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem); - it=s3.begin(); - while(it!=s3.end()) - { - switch((*it)->GetType()) - { - case SMDSAbs_Node: - MESSAGE("Internal Error: This should not happen"); - break; - case SMDSAbs_Edge: - myEdges.erase(static_cast( - const_cast(*it))); - break; - case SMDSAbs_Face: - myFaces.erase(static_cast( - const_cast(*it))); - break; - case SMDSAbs_Volume: - myVolumes.erase(static_cast( - const_cast(*it))); - break; - } - delete (*it); - it++; - } - if(removenodes) - { - it=s2->begin(); - while(it!=s2->end()) - { - myNodes.erase(static_cast( - const_cast(*it))); - delete *it; - it++; - } - } - - delete s2; - delete s1; -} - -/** - * Concat the coordinates of all nodes in an array. - * Its used to display the mesh. - * @return A array of size 3*NbNodes() containing the coordinates of nodes. - */ -double * SMDS_Mesh::getNodesCoordinates() -{ - double * toReturn=new double[3*NbNodes()]; - SMDS_Iterator * it=nodesIterator(); - int i=0; - while(it->more()) - { - const SMDS_MeshNode * n=it->next(); - toReturn[i]=n->X(); - i++; - toReturn[i]=n->Y(); - i++; - toReturn[i]=n->Z(); - i++; - } - delete it; - return toReturn; -} - -/** - * Concat the id of all nodes in an array. - * Its used to display the mesh. - * @return A array of size NbNodes() containing the ids of nodes. - */ -long * SMDS_Mesh::getNodesID() -{ - long * toReturn=new long[NbNodes()]; - SMDS_Iterator * it=nodesIterator(); - int i=0; - while(it->more()) - { - const SMDS_MeshNode * n=it->next(); - toReturn[i]=n->GetID(); - i++; - } - delete it; - return toReturn; -} - -/** - * Concat the id of nodes of edges in an array. - * Array format is {edge_id, node1_id, node2_id} - * Its used to display the mesh. - * @return A array of size 3*NbEdges() containing the edges. - */ -long * SMDS_Mesh::getEdgesIndices() -{ - long * toReturn=new long[NbEdges()*3]; - SMDS_Iterator * it=edgesIterator(); - int i=0; - - while(it->more()) - { - const SMDS_MeshEdge * e=it->next(); - toReturn[i]=e->GetID(); - i++; - SMDS_Iterator * itn=e->nodesIterator(); - while(itn->more()) - { - const SMDS_MeshElement * n=itn->next(); - toReturn[i]=n->GetID(); - i++; - } - delete itn; - } - delete it; - return toReturn; + list removedElems; + list removedNodes; + RemoveElement( elem, removedElems, removedNodes, removenodes ); } - -/** - * Concat the id of nodes of triangles in an array. - * Array format is {tria_id, node1_id, node2_id, node3_id} - * Its used to display the mesh. - * @return A array of size 4*NbTriangles() containing the edges. - */ -long * SMDS_Mesh::getTrianglesIndices() -{ - long * toReturn=new long[NbTriangles()*4]; - SMDS_Iterator * it=facesIterator(); - int i=0; - while(it->more()) - { - const SMDS_MeshFace * f=it->next(); - if(f->NbNodes()==3) - { - toReturn[i]=f->GetID(); - i++; - SMDS_Iterator * itn=f->nodesIterator(); - while(itn->more()) - { - const SMDS_MeshElement * n=itn->next(); - toReturn[i]=n->GetID(); - i++; - } - delete itn; - } - } - delete it; - return toReturn; -} - -/** - * Return the number of 3 nodes faces in the mesh. - * This method run in O(n). - * @return The number of face whose number of nodes is 3 + +/////////////////////////////////////////////////////////////////////////////// +///@param elem The element to delete +///@param removedElems contains all removed elements +///@param removedNodes contains all removed nodes +///@param removenodes if true remaining nodes will be removed +/////////////////////////////////////////////////////////////////////////////// +void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, + list& removedElems, + list& removedNodes, + const bool removenodes) +{ + // get finite elements built on elem + set * s1; + if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge || + !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face) + { + s1 = new set(); + s1->insert(elem); + } + else + s1 = getFinitElements(elem); + + // get exclusive nodes (which would become free afterwards) + set * s2; + if (s1->empty() && elem->GetType() == SMDSAbs_Node) + { + s2 = new set(); + s2->insert(elem); + } + else + s2 = getExclusiveNodes(*s1); + + // form the set of finite and construction elements to remove + set s3; + set::iterator it=s1->begin(); + while(it!=s1->end()) + { + addChildrenWithNodes(s3, *it ,*s2); + s3.insert(*it); + it++; + } + if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem); + + // remove finite and construction elements + it=s3.begin(); + while(it!=s3.end()) + { + // Remove element from of its nodes + SMDS_ElemIteratorPtr itn=(*it)->nodesIterator(); + while(itn->more()) + { + SMDS_MeshNode * n = static_cast + (const_cast(itn->next())); + n->RemoveInverseElement( (*it) ); + } + + switch((*it)->GetType()) + { + case SMDSAbs_Node: + MESSAGE("Internal Error: This should not happen"); + break; + case SMDSAbs_Edge: + myEdges.erase(static_cast + (const_cast(*it))); + break; + case SMDSAbs_Face: + myFaces.erase(static_cast + (const_cast(*it))); + break; + case SMDSAbs_Volume: + myVolumes.erase(static_cast + (const_cast(*it))); + break; + } + //MESSAGE( "SMDS: RM elem " << (*it)->GetID() ); + removedElems.push_back( (*it) ); + myElementIDFactory->ReleaseID((*it)->GetID()); + delete (*it); + it++; + } + + // remove exclusive (free) nodes + if(removenodes) + { + it=s2->begin(); + while(it!=s2->end()) + { + //MESSAGE( "SMDS: RM node " << (*it)->GetID() ); + myNodes.erase(static_cast + (const_cast(*it))); + myNodeIDFactory->ReleaseID((*it)->GetID()); + removedNodes.push_back( (*it) ); + delete *it; + it++; + } + } + + delete s2; + delete s1; +} + +/*! + * Checks if the element is present in mesh. + * Useful to determine dead pointers. */ -int SMDS_Mesh::NbTriangles() const -{ - SMDS_Iterator * it=facesIterator(); - int toReturn=0; - while(it->more()) - { - const SMDS_MeshFace * f=it->next(); - if(f->NbNodes()==3) toReturn++; - } - return toReturn; +bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const +{ + // we should not imply on validity of *elem, so iterate on containers + // of all types in the hope of finding somewhere there + SMDS_NodeIteratorPtr itn = nodesIterator(); + while (itn->more()) + if (elem == itn->next()) + return true; + SMDS_EdgeIteratorPtr ite = edgesIterator(); + while (ite->more()) + if (elem == ite->next()) + return true; + SMDS_FaceIteratorPtr itf = facesIterator(); + while (itf->more()) + if (elem == itf->next()) + return true; + SMDS_VolumeIteratorPtr itv = volumesIterator(); + while (itv->more()) + if (elem == itv->next()) + return true; + return false; } diff --git a/src/SMDS/SMDS_Mesh.hxx b/src/SMDS/SMDS_Mesh.hxx index 47c22b079..615071991 100644 --- a/src/SMDS/SMDS_Mesh.hxx +++ b/src/SMDS/SMDS_Mesh.hxx @@ -34,207 +34,281 @@ #include "SMDS_MeshElementIDFactory.hxx" #include "SMDS_Iterator.hxx" +#include #include #include class SMDSControl_BoundaryEdges; -class SMDS_Mesh:public SMDS_MeshObject -{ - - public: - - SMDS_Mesh(); - - SMDS_Iterator * nodesIterator() const; - SMDS_Iterator * edgesIterator() const; - SMDS_Iterator * facesIterator() const; - SMDS_Iterator * volumesIterator() const; - - SMDS_Mesh *AddSubMesh(); - virtual SMDS_MeshNode* AddNode(double x, double y, double z); - virtual SMDS_MeshNode* AddNodeWithID(double x, double y, double z, int ID); - - virtual SMDS_MeshEdge* AddEdge( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2); - virtual SMDS_MeshFace* AddFace( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3); - virtual SMDS_MeshFace* AddFace( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4); - virtual SMDS_MeshVolume* AddVolume( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4); - virtual SMDS_MeshVolume* AddVolume( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5); - virtual SMDS_MeshVolume* AddVolume( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6); - virtual SMDS_MeshVolume* AddVolume( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, - const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8); - - SMDS_MeshEdge* AddEdgeWithID(int n1, int n2, int ID); - SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int ID); - SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4, - int ID); - SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, - int ID); - SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, - int n5, int ID); - SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, - int n5, int n6, int ID); - SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, - int n5, int n6, int n7, int n8, int ID); - - SMDS_MeshEdge* AddEdgeWithID( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, int ID); - SMDS_MeshFace* AddFaceWithID( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, int ID); - SMDS_MeshFace* AddFaceWithID( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, int ID); - SMDS_MeshVolume* AddVolumeWithID( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, int ID); - SMDS_MeshVolume* AddVolumeWithID( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, int ID); - SMDS_MeshVolume* AddVolumeWithID( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, int ID); - SMDS_MeshVolume* AddVolumeWithID( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, - const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, int ID); - - virtual void RemoveElement(const SMDS_MeshElement * elem, const bool removenodes = - false); - virtual void RemoveNode(const SMDS_MeshNode * node); - virtual void RemoveEdge(const SMDS_MeshEdge * edge); - virtual void RemoveFace(const SMDS_MeshFace * face); - virtual void RemoveVolume(const SMDS_MeshVolume * volume); - - virtual bool RemoveFromParent(); - virtual bool RemoveSubMesh(const SMDS_Mesh * aMesh); - - const SMDS_MeshNode *FindNode(int idnode) const; - const SMDS_MeshEdge *FindEdge(int idnode1, int idnode2) const; - const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3) const; - const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3, int idnode4) const; - const SMDS_MeshElement *FindElement(int IDelem) const; +typedef SMDS_Iterator SMDS_NodeIterator; +typedef boost::shared_ptr > SMDS_NodeIteratorPtr; +typedef SMDS_Iterator SMDS_EdgeIterator; +typedef boost::shared_ptr > SMDS_EdgeIteratorPtr; +typedef SMDS_Iterator SMDS_FaceIterator; +typedef boost::shared_ptr > SMDS_FaceIteratorPtr; +typedef SMDS_Iterator SMDS_VolumeIterator; +typedef boost::shared_ptr > SMDS_VolumeIteratorPtr; + +class SMDS_Mesh:public SMDS_MeshObject{ +public: + + SMDS_Mesh(); + + SMDS_NodeIteratorPtr nodesIterator() const; + SMDS_EdgeIteratorPtr edgesIterator() const; + SMDS_FaceIteratorPtr facesIterator() const; + SMDS_VolumeIteratorPtr volumesIterator() const; + + SMDS_Mesh *AddSubMesh(); + + virtual SMDS_MeshNode* AddNodeWithID(double x, double y, double z, int ID); + virtual SMDS_MeshNode* AddNode(double x, double y, double z); + + virtual SMDS_MeshEdge* AddEdgeWithID(int n1, int n2, int ID); + virtual SMDS_MeshEdge* AddEdgeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + int ID); + virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2); + + virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int ID); + virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + int ID); + virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3); + + virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4, int ID); + virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + int ID); + virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4); + + virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshEdge * e1, + const SMDS_MeshEdge * e2, + const SMDS_MeshEdge * e3, int ID); + virtual SMDS_MeshFace* AddFace(const SMDS_MeshEdge * e1, + const SMDS_MeshEdge * e2, + const SMDS_MeshEdge * e3); + + virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshEdge * e1, + const SMDS_MeshEdge * e2, + const SMDS_MeshEdge * e3, + const SMDS_MeshEdge * e4, int ID); + virtual SMDS_MeshFace* AddFace(const SMDS_MeshEdge * e1, + const SMDS_MeshEdge * e2, + const SMDS_MeshEdge * e3, + const SMDS_MeshEdge * e4); + + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4); + + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, + int n5, int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5); + + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, + int n5, int n6, int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6); + + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, + int n5, int n6, int n7, int n8, int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8); + + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4); + + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + const SMDS_MeshFace * f5, int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + const SMDS_MeshFace * f5); + + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + const SMDS_MeshFace * f5, + const SMDS_MeshFace * f6, int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshFace * f1, + const SMDS_MeshFace * f2, + const SMDS_MeshFace * f3, + const SMDS_MeshFace * f4, + const SMDS_MeshFace * f5, + const SMDS_MeshFace * f6); + + virtual void RemoveElement(const SMDS_MeshElement * elem, + list& removedElems, + list& removedNodes, + const bool removenodes = false); + virtual void RemoveElement(const SMDS_MeshElement * elem, const bool removenodes = false); + virtual void RemoveNode(const SMDS_MeshNode * node); + virtual void RemoveEdge(const SMDS_MeshEdge * edge); + virtual void RemoveFace(const SMDS_MeshFace * face); + virtual void RemoveVolume(const SMDS_MeshVolume * volume); + + virtual bool RemoveFromParent(); + virtual bool RemoveSubMesh(const SMDS_Mesh * aMesh); + + const SMDS_MeshNode *FindNode(int idnode) const; + const SMDS_MeshEdge *FindEdge(int idnode1, int idnode2) const; + const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3) const; + const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3, int idnode4) const; + const SMDS_MeshElement *FindElement(int IDelem) const; - int NbNodes() const; - int NbEdges() const; - int NbFaces() const; - int NbTriangles() const; - int NbVolumes() const; - int NbSubMesh() const; - void DumpNodes() const; - void DumpEdges() const; - void DumpFaces() const; - void DumpVolumes() const; - void DebugStats() const; - SMDS_Mesh *boundaryFaces(); - SMDS_Mesh *boundaryEdges(); - virtual ~SMDS_Mesh(); - bool hasConstructionEdges(); - bool hasConstructionFaces(); - bool hasInverseElements(); - void setConstructionEdges(bool); - void setConstructionFaces(bool); - void setInverseElements(bool); - - double * getNodesCoordinates(); - long * getNodesID(); - long * getEdgesIndices(); - long * getTrianglesIndices(); - - private: - SMDS_Mesh(SMDS_Mesh * parent); - SMDS_MeshFace * createTriangle(SMDS_MeshNode * node1, - SMDS_MeshNode * node2, SMDS_MeshNode * node3); - SMDS_MeshFace * createQuadrangle(SMDS_MeshNode * node1, - SMDS_MeshNode * node2, SMDS_MeshNode * node3, SMDS_MeshNode * node4); - const SMDS_MeshEdge* FindEdge(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2) const; - SMDS_MeshEdge* FindEdgeOrCreate(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2); - SMDS_MeshFace* FindFaceOrCreate( - const SMDS_MeshNode *n1, - const SMDS_MeshNode *n2, - const SMDS_MeshNode *n3); - const SMDS_MeshFace* FindFace( - const SMDS_MeshNode *n1, - const SMDS_MeshNode *n2, - const SMDS_MeshNode *n3, - const SMDS_MeshNode *n4) const; - SMDS_MeshFace* FindFaceOrCreate( - const SMDS_MeshNode *n1, - const SMDS_MeshNode *n2, - const SMDS_MeshNode *n3, - const SMDS_MeshNode *n4); - void addChildrenWithNodes(set& setOfChildren, - const SMDS_MeshElement * element, set& nodes); - - // Fields PRIVATE - typedef set SetOfNodes; - typedef set SetOfEdges; - typedef set SetOfFaces; - typedef set SetOfVolumes; - - SetOfNodes myNodes; - SetOfEdges myEdges; - SetOfFaces myFaces; - SetOfVolumes myVolumes; - SMDS_Mesh *myParent; - list myChildren; - SMDS_MeshElementIDFactory *myNodeIDFactory; - SMDS_MeshElementIDFactory *myElementIDFactory; - - bool myHasConstructionEdges; - bool myHasConstructionFaces; - bool myHasInverseElements; + int NbNodes() const; + int NbEdges() const; + int NbFaces() const; + int NbVolumes() const; + int NbSubMesh() const; + void DumpNodes() const; + void DumpEdges() const; + void DumpFaces() const; + void DumpVolumes() const; + void DebugStats() const; + SMDS_Mesh *boundaryFaces(); + SMDS_Mesh *boundaryEdges(); + virtual ~SMDS_Mesh(); + bool hasConstructionEdges(); + bool hasConstructionFaces(); + bool hasInverseElements(); + void setConstructionEdges(bool); + void setConstructionFaces(bool); + void setInverseElements(bool); + + /*! + * Checks if the element is present in mesh. + * Useful to determine dead pointers. + * Use this function for debug purpose only! Do not check in the code + * using it even in _DEBUG_ mode + */ + bool Contains (const SMDS_MeshElement* elem) const; + + typedef set SetOfNodes; + typedef set SetOfEdges; + typedef set SetOfFaces; + typedef set SetOfVolumes; + +private: + SMDS_Mesh(SMDS_Mesh * parent); + + SMDS_MeshFace * createTriangle(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3); + + SMDS_MeshFace * createQuadrangle(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4); + + bool registerElement(int ID, SMDS_MeshElement * element); + + const SMDS_MeshEdge* FindEdge(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2) const; + + SMDS_MeshEdge* FindEdgeOrCreate(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2); + + const SMDS_MeshFace* FindFace(const SMDS_MeshNode *n1, + const SMDS_MeshNode *n2, + const SMDS_MeshNode *n3) const; + + SMDS_MeshFace* FindFaceOrCreate(const SMDS_MeshNode *n1, + const SMDS_MeshNode *n2, + const SMDS_MeshNode *n3); + + const SMDS_MeshFace* FindFace(const SMDS_MeshNode *n1, + const SMDS_MeshNode *n2, + const SMDS_MeshNode *n3, + const SMDS_MeshNode *n4) const; + + SMDS_MeshFace* FindFaceOrCreate(const SMDS_MeshNode *n1, + const SMDS_MeshNode *n2, + const SMDS_MeshNode *n3, + const SMDS_MeshNode *n4); + + void addChildrenWithNodes(set& setOfChildren, + const SMDS_MeshElement * element, + set& nodes); + + // Fields PRIVATE + + SetOfNodes myNodes; + SetOfEdges myEdges; + SetOfFaces myFaces; + SetOfVolumes myVolumes; + SMDS_Mesh *myParent; + list myChildren; + SMDS_MeshElementIDFactory *myNodeIDFactory; + SMDS_MeshElementIDFactory *myElementIDFactory; + + bool myHasConstructionEdges; + bool myHasConstructionFaces; + bool myHasInverseElements; }; #endif diff --git a/src/SMDS/SMDS_MeshEdge.cxx b/src/SMDS/SMDS_MeshEdge.cxx index 3f7994c1f..484207ba0 100644 --- a/src/SMDS/SMDS_MeshEdge.cxx +++ b/src/SMDS/SMDS_MeshEdge.cxx @@ -36,7 +36,8 @@ //purpose : //======================================================================= -SMDS_MeshEdge::SMDS_MeshEdge(SMDS_MeshNode * node1, SMDS_MeshNode * node2) +SMDS_MeshEdge::SMDS_MeshEdge(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2) { myNodes[0]=node1; myNodes[1]=node2; @@ -68,36 +69,40 @@ SMDSAbs_ElementType SMDS_MeshEdge::GetType() const return SMDSAbs_Edge; } -SMDS_Iterator * SMDS_MeshEdge:: +class SMDS_MeshEdge_MyNodeIterator:public SMDS_ElemIterator +{ + const SMDS_MeshNode *const* myNodes; + int myIndex; + public: + SMDS_MeshEdge_MyNodeIterator(const SMDS_MeshNode * const* nodes): + myNodes(nodes),myIndex(0) {} + + bool more() + { + return myIndex<2; + } + + const SMDS_MeshElement* next() + { + myIndex++; + return myNodes[myIndex-1]; + } +}; + +SMDS_ElemIteratorPtr SMDS_MeshEdge:: elementsIterator(SMDSAbs_ElementType type) const { - class MyNodeIterator:public SMDS_Iterator - { - SMDS_MeshNode *const* myNodes; - int myIndex; - public: - MyNodeIterator(SMDS_MeshNode * const* nodes):myNodes(nodes),myIndex(0) - {} - - bool more() - { - return myIndex<2; - } - - const SMDS_MeshElement* next() - { - myIndex++; - return myNodes[myIndex-1]; - } - }; - - switch(type) - { - case SMDSAbs_Edge:return SMDS_MeshElement::elementsIterator(SMDSAbs_Edge); - case SMDSAbs_Node:return new MyNodeIterator(myNodes); - default: return new SMDS_IteratorOfElements(this,type, nodesIterator()); - } - + switch(type) + { + case SMDSAbs_Edge: + return SMDS_MeshElement::elementsIterator(SMDSAbs_Edge); + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new SMDS_MeshEdge_MyNodeIterator(myNodes)); + default: + return SMDS_ElemIteratorPtr + (new SMDS_IteratorOfElements + (this,type, SMDS_ElemIteratorPtr(new SMDS_MeshEdge_MyNodeIterator(myNodes)))); + } } bool operator<(const SMDS_MeshEdge & e1, const SMDS_MeshEdge & e2) diff --git a/src/SMDS/SMDS_MeshEdge.hxx b/src/SMDS/SMDS_MeshEdge.hxx index cfef08ed7..28621d8e9 100644 --- a/src/SMDS/SMDS_MeshEdge.hxx +++ b/src/SMDS/SMDS_MeshEdge.hxx @@ -34,7 +34,8 @@ class SMDS_MeshEdge:public SMDS_MeshElement { public: - SMDS_MeshEdge(SMDS_MeshNode * node1, SMDS_MeshNode * node2); + SMDS_MeshEdge(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2); void Print(ostream & OS) const; SMDSAbs_ElementType GetType() const; @@ -42,11 +43,11 @@ class SMDS_MeshEdge:public SMDS_MeshElement int NbEdges() const; friend bool operator<(const SMDS_MeshEdge& e1, const SMDS_MeshEdge& e2); protected: - SMDS_Iterator * + SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; private: - SMDS_MeshNode* myNodes[2]; + const SMDS_MeshNode* myNodes[2]; }; #endif diff --git a/src/SMDS/SMDS_MeshElement.cxx b/src/SMDS/SMDS_MeshElement.cxx index 701e6fe97..14c0af4b5 100644 --- a/src/SMDS/SMDS_MeshElement.cxx +++ b/src/SMDS/SMDS_MeshElement.cxx @@ -45,7 +45,7 @@ ostream & operator <<(ostream & OS, const SMDS_MeshElement * ME) /// Create an iterator which iterate on nodes owned by the element. /// This method call elementsIterator(). /////////////////////////////////////////////////////////////////////////////// -SMDS_Iterator * SMDS_MeshElement::nodesIterator() const +SMDS_ElemIteratorPtr SMDS_MeshElement::nodesIterator() const { return elementsIterator(SMDSAbs_Node); } @@ -54,7 +54,7 @@ SMDS_Iterator * SMDS_MeshElement::nodesIterator() cons /// Create an iterator which iterate on edges linked with or owned by the element. /// This method call elementsIterator(). /////////////////////////////////////////////////////////////////////////////// -SMDS_Iterator * SMDS_MeshElement::edgesIterator() const +SMDS_ElemIteratorPtr SMDS_MeshElement::edgesIterator() const { return elementsIterator(SMDSAbs_Edge); } @@ -63,7 +63,7 @@ SMDS_Iterator * SMDS_MeshElement::edgesIterator() cons /// Create an iterator which iterate on faces linked with or owned by the element. /// This method call elementsIterator(). /////////////////////////////////////////////////////////////////////////////// -SMDS_Iterator * SMDS_MeshElement::facesIterator() const +SMDS_ElemIteratorPtr SMDS_MeshElement::facesIterator() const { return elementsIterator(SMDSAbs_Face); } @@ -74,13 +74,12 @@ SMDS_Iterator * SMDS_MeshElement::facesIterator() cons int SMDS_MeshElement::NbNodes() const { int nbnodes=0; - SMDS_Iterator * it=nodesIterator(); + SMDS_ElemIteratorPtr it=nodesIterator(); while(it->more()) { it->next(); nbnodes++; } - delete it; return nbnodes; } @@ -90,13 +89,12 @@ int SMDS_MeshElement::NbNodes() const int SMDS_MeshElement::NbEdges() const { int nbedges=0; - SMDS_Iterator * it=edgesIterator(); + SMDS_ElemIteratorPtr it=edgesIterator(); while(it->more()) { it->next(); nbedges++; } - delete it; return nbedges; } @@ -106,55 +104,52 @@ int SMDS_MeshElement::NbEdges() const int SMDS_MeshElement::NbFaces() const { int nbfaces=0; - SMDS_Iterator * it=facesIterator(); + SMDS_ElemIteratorPtr it=facesIterator(); while(it->more()) { it->next(); nbfaces++; } - delete it; return nbfaces; } /////////////////////////////////////////////////////////////////////////////// -///Create and iterator which iterate on elements linked with the current element. -///The iterator must be free by the caller (call delete myIterator). +///Create an iterator which iterate on elements linked with the current element. ///@param type The of elements on which you want to iterate -///@return An iterator, that you must free when you no longer need it +///@return A smart pointer to iterator, you are not to take care of freeing memory /////////////////////////////////////////////////////////////////////////////// -SMDS_Iterator * SMDS_MeshElement:: +class SMDS_MeshElement_MyIterator:public SMDS_ElemIterator +{ + const SMDS_MeshElement * myElement; + bool myMore; + public: + SMDS_MeshElement_MyIterator(const SMDS_MeshElement * element): + myElement(element),myMore(true) {} + + bool more() + { + return myMore; + } + + const SMDS_MeshElement* next() + { + myMore=false; + return myElement; + } +}; +SMDS_ElemIteratorPtr SMDS_MeshElement:: elementsIterator(SMDSAbs_ElementType type) const { /** @todo Check that iterator in the child classes return elements in the same order for each different implementation (i.e: SMDS_VolumeOfNodes and SMDS_VolumeOfFaces */ - class MyIterator:public SMDS_Iterator - { - const SMDS_MeshElement * myElement; - bool myMore; - public: - MyIterator(const SMDS_MeshElement * element): - myElement(element),myMore(true) - { - } - - bool more() - { - return myMore; - } - - const SMDS_MeshElement* next() - { - myMore=false; - return myElement; - } - }; - if(type==GetType()) return new MyIterator(this); + if(type==GetType()) + return SMDS_ElemIteratorPtr(new SMDS_MeshElement_MyIterator(this)); else { - MESSAGE("Iterator not implemented"); - return NULL; + MESSAGE("Iterator not implemented"); + return SMDS_ElemIteratorPtr((SMDS_ElemIterator*)NULL); } } diff --git a/src/SMDS/SMDS_MeshElement.hxx b/src/SMDS/SMDS_MeshElement.hxx index 86bc6ddb5..5ae8bc1a0 100644 --- a/src/SMDS/SMDS_MeshElement.hxx +++ b/src/SMDS/SMDS_MeshElement.hxx @@ -32,6 +32,7 @@ #include "SMDS_Iterator.hxx" #include "SMDS_MeshElementIDFactory.hxx" +#include #include #include @@ -39,6 +40,10 @@ using namespace std; class SMDS_MeshNode; class SMDS_MeshEdge; class SMDS_MeshFace; +class SMDS_MeshElement; + +typedef SMDS_Iterator SMDS_ElemIterator; +typedef boost::shared_ptr > SMDS_ElemIteratorPtr; /////////////////////////////////////////////////////////////////////////////// /// Base class for elements @@ -47,10 +52,10 @@ class SMDS_MeshElement:public SMDS_MeshObject { public: - SMDS_Iterator * nodesIterator() const; - SMDS_Iterator * edgesIterator() const; - SMDS_Iterator * facesIterator() const; - virtual SMDS_Iterator * + SMDS_ElemIteratorPtr nodesIterator() const; + SMDS_ElemIteratorPtr edgesIterator() const; + SMDS_ElemIteratorPtr facesIterator() const; + virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; virtual int NbNodes() const; diff --git a/src/SMDS/SMDS_MeshElementIDFactory.cxx b/src/SMDS/SMDS_MeshElementIDFactory.cxx index d635b0110..43f12c777 100644 --- a/src/SMDS/SMDS_MeshElementIDFactory.cxx +++ b/src/SMDS/SMDS_MeshElementIDFactory.cxx @@ -58,3 +58,27 @@ SMDS_MeshElement* SMDS_MeshElementIDFactory::MeshElement(int ID) map::iterator it=myIDElements.find(ID); if(it==myIDElements.end()) return NULL; else return (*it).second; } + + +//======================================================================= +//function : GetFreeID +//purpose : +//======================================================================= +int SMDS_MeshElementIDFactory::GetFreeID() +{ + int ID; + do { + ID = SMDS_MeshIDFactory::GetFreeID(); + } while (myIDElements.find(ID) != myIDElements.end()); + return ID; +} + +//======================================================================= +//function : ReleaseID +//purpose : +//======================================================================= +void SMDS_MeshElementIDFactory::ReleaseID(const int ID) +{ + myIDElements.erase(ID); + SMDS_MeshIDFactory::ReleaseID(ID); +} diff --git a/src/SMDS/SMDS_MeshElementIDFactory.hxx b/src/SMDS/SMDS_MeshElementIDFactory.hxx index 881467633..f987eaed2 100644 --- a/src/SMDS/SMDS_MeshElementIDFactory.hxx +++ b/src/SMDS/SMDS_MeshElementIDFactory.hxx @@ -28,7 +28,6 @@ #define _SMDS_MeshElementIDFactory_HeaderFile #include "SMDS_MeshIDFactory.hxx" -#include #include using namespace std; @@ -41,6 +40,8 @@ class SMDS_MeshElementIDFactory:public SMDS_MeshIDFactory SMDS_MeshElementIDFactory(); bool BindID(int ID, SMDS_MeshElement * elem); SMDS_MeshElement * MeshElement(int ID); + virtual int GetFreeID(); + virtual void ReleaseID(int ID); private: map myIDElements; diff --git a/src/SMDS/SMDS_MeshGroup.cxx b/src/SMDS/SMDS_MeshGroup.cxx index 25e942abb..25ae25b73 100644 --- a/src/SMDS/SMDS_MeshGroup.cxx +++ b/src/SMDS/SMDS_MeshGroup.cxx @@ -32,8 +32,9 @@ using namespace std; //purpose : //======================================================================= -SMDS_MeshGroup::SMDS_MeshGroup(const SMDS_Mesh * aMesh) - :myMesh(aMesh),myType(SMDSAbs_All), myParent(NULL) +SMDS_MeshGroup::SMDS_MeshGroup(const SMDS_Mesh * theMesh, + const SMDSAbs_ElementType theType) + :myMesh(theMesh),myType(theType), myParent(NULL) { } @@ -42,8 +43,9 @@ SMDS_MeshGroup::SMDS_MeshGroup(const SMDS_Mesh * aMesh) //purpose : //======================================================================= -SMDS_MeshGroup::SMDS_MeshGroup(SMDS_MeshGroup * parent) - :myMesh(parent->myMesh),myType(SMDSAbs_All), myParent(parent) +SMDS_MeshGroup::SMDS_MeshGroup(SMDS_MeshGroup * theParent, + const SMDSAbs_ElementType theType) + :myMesh(theParent->myMesh),myType(theType), myParent(theParent) { } @@ -52,9 +54,10 @@ SMDS_MeshGroup::SMDS_MeshGroup(SMDS_MeshGroup * parent) //purpose : //======================================================================= -const SMDS_MeshGroup *SMDS_MeshGroup::AddSubGroup() +const SMDS_MeshGroup *SMDS_MeshGroup::AddSubGroup + (const SMDSAbs_ElementType theType) { - const SMDS_MeshGroup * subgroup = new SMDS_MeshGroup(this); + const SMDS_MeshGroup * subgroup = new SMDS_MeshGroup(this,theType); myChildren.insert(myChildren.end(),subgroup); return subgroup; } @@ -64,14 +67,14 @@ const SMDS_MeshGroup *SMDS_MeshGroup::AddSubGroup() //purpose : //======================================================================= -bool SMDS_MeshGroup::RemoveSubGroup(const SMDS_MeshGroup * aGroup) +bool SMDS_MeshGroup::RemoveSubGroup(const SMDS_MeshGroup * theGroup) { bool found = false; list::iterator itgroup; for(itgroup=myChildren.begin(); itgroup!=myChildren.end(); itgroup++) { const SMDS_MeshGroup* subgroup=*itgroup; - if (subgroup == aGroup) + if (subgroup == theGroup) { found = true; myChildren.erase(itgroup); @@ -106,39 +109,19 @@ void SMDS_MeshGroup::Clear() myType = SMDSAbs_All; } -//======================================================================= -//function : IsEmpty -//purpose : -//======================================================================= - -bool SMDS_MeshGroup::IsEmpty() const -{ - return myElements.empty(); -} - -//======================================================================= -//function : Extent -//purpose : -//======================================================================= - -int SMDS_MeshGroup::Extent() const -{ - return myElements.size(); -} - //======================================================================= //function : Add //purpose : //======================================================================= -void SMDS_MeshGroup::Add(const SMDS_MeshElement * ME) +void SMDS_MeshGroup::Add(const SMDS_MeshElement * theElem) { // the type of the group is determined by the first element added - if (myElements.empty()) myType = ME->GetType(); - else if (ME->GetType() != myType) + if (myElements.empty()) myType = theElem->GetType(); + else if (theElem->GetType() != myType) MESSAGE("SMDS_MeshGroup::Add : Type Mismatch"); - myElements.insert(ME); + myElements.insert(theElem); } //======================================================================= @@ -146,28 +129,29 @@ void SMDS_MeshGroup::Add(const SMDS_MeshElement * ME) //purpose : //======================================================================= -void SMDS_MeshGroup::Remove(const SMDS_MeshElement * ME) +void SMDS_MeshGroup::Remove(const SMDS_MeshElement * theElem) { - myElements.erase(ME); + myElements.erase(theElem); if (myElements.empty()) myType = SMDSAbs_All; } //======================================================================= -//function : Type +//function : Contains //purpose : //======================================================================= -SMDSAbs_ElementType SMDS_MeshGroup::Type() const +bool SMDS_MeshGroup::Contains(const SMDS_MeshElement * theElem) const { - return myType; + return myElements.find(theElem)!=myElements.end(); } //======================================================================= -//function : Contains +//function : SetType //purpose : //======================================================================= -bool SMDS_MeshGroup::Contains(const SMDS_MeshElement * ME) const +void SMDS_MeshGroup::SetType(const SMDSAbs_ElementType theType) { - return myElements.find(ME)!=myElements.end(); + if (IsEmpty()) + myType = theType; } diff --git a/src/SMDS/SMDS_MeshGroup.hxx b/src/SMDS/SMDS_MeshGroup.hxx index f73c1dd1f..c5bfcb432 100644 --- a/src/SMDS/SMDS_MeshGroup.hxx +++ b/src/SMDS/SMDS_MeshGroup.hxx @@ -33,25 +33,44 @@ using namespace std; class SMDS_MeshGroup:public SMDS_MeshObject { public: - SMDS_MeshGroup(const SMDS_Mesh * aMesh); - const SMDS_MeshGroup * AddSubGroup(); - virtual bool RemoveSubGroup(const SMDS_MeshGroup* aGroup); + SMDS_MeshGroup(const SMDS_Mesh * theMesh, + const SMDSAbs_ElementType theType = SMDSAbs_All); + const SMDS_MeshGroup * AddSubGroup + (const SMDSAbs_ElementType theType = SMDSAbs_All); + virtual bool RemoveSubGroup(const SMDS_MeshGroup* theGroup); virtual bool RemoveFromParent(); - void Clear(); - void Add(const SMDS_MeshElement * ME); - void Remove(const SMDS_MeshElement * ME); - bool IsEmpty() const; - int Extent() const; - SMDSAbs_ElementType Type() const; - bool Contains(const SMDS_MeshElement * ME) const; - - ~SMDS_MeshGroup(); + + const SMDS_Mesh* GetMesh() const { return myMesh; } + + void SetType (const SMDSAbs_ElementType theType); + void Clear(); + void Add(const SMDS_MeshElement * theElem); + void Remove(const SMDS_MeshElement * theElem); + bool IsEmpty() const { return myElements.empty(); } + int Extent() const { return myElements.size(); } + + SMDSAbs_ElementType GetType() const { return myType; } + + bool Contains(const SMDS_MeshElement * theElem) const; + + void InitIterator() const + { const_cast(myIterator) = myElements.begin(); } + + bool More() const { return myIterator != myElements.end(); } + + const SMDS_MeshElement* Next() const + { return *(const_cast(myIterator))++; } + private: - SMDS_MeshGroup(SMDS_MeshGroup* parent); - const SMDS_Mesh *myMesh; - SMDSAbs_ElementType myType; - set myElements; - SMDS_MeshGroup * myParent; - list myChildren; + SMDS_MeshGroup(SMDS_MeshGroup* theParent, + const SMDSAbs_ElementType theType = SMDSAbs_All); + + typedef set::iterator iterator; + const SMDS_Mesh * myMesh; + SMDSAbs_ElementType myType; + set myElements; + SMDS_MeshGroup * myParent; + list myChildren; + iterator myIterator; }; #endif diff --git a/src/SMDS/SMDS_MeshIDFactory.cxx b/src/SMDS/SMDS_MeshIDFactory.cxx index a68ae5ad0..db5df4222 100644 --- a/src/SMDS/SMDS_MeshIDFactory.cxx +++ b/src/SMDS/SMDS_MeshIDFactory.cxx @@ -54,5 +54,5 @@ int SMDS_MeshIDFactory::GetFreeID() //======================================================================= void SMDS_MeshIDFactory::ReleaseID(const int ID) { - if (ID < myMaxID) myPoolOfID.push(ID); + if (ID > 0 && ID < myMaxID) myPoolOfID.push(ID); } diff --git a/src/SMDS/SMDS_MeshNode.cxx b/src/SMDS/SMDS_MeshNode.cxx index 20bce6369..cba7920fa 100644 --- a/src/SMDS/SMDS_MeshNode.cxx +++ b/src/SMDS/SMDS_MeshNode.cxx @@ -61,7 +61,7 @@ void SMDS_MeshNode::Print(ostream & OS) const //purpose : //======================================================================= -void SMDS_MeshNode::SetPosition(SMDS_Position * aPos) +void SMDS_MeshNode::SetPosition(const SMDS_PositionPtr& aPos) { myPosition = aPos; } @@ -71,94 +71,92 @@ void SMDS_MeshNode::SetPosition(SMDS_Position * aPos) //purpose : //======================================================================= -SMDS_Position *SMDS_MeshNode::GetPosition() +const SMDS_PositionPtr& SMDS_MeshNode::GetPosition() const { return myPosition; } -const SMDS_Position *SMDS_MeshNode::GetPosition() const +class SMDS_MeshNode_MyInvIterator:public SMDS_ElemIterator { - return myPosition; -} -/** -*/ -SMDS_Iterator * SMDS_MeshNode:: + const set& mySet; + set::iterator myIterator; + public: + SMDS_MeshNode_MyInvIterator(const set& s): + mySet(s) + { + myIterator=mySet.begin(); + } + + bool more() + { + return myIterator!=mySet.end(); + } + + const SMDS_MeshElement* next() + { + const SMDS_MeshElement* current=*myIterator; + myIterator++; + return current; + } +}; + +SMDS_ElemIteratorPtr SMDS_MeshNode:: GetInverseElementIterator() const { - class SMDS_InverseElementIterator:public SMDS_Iterator - { - const set& mySet; - set::iterator myIterator; - public: - SMDS_InverseElementIterator(const set& s):mySet(s) - { - myIterator=mySet.begin(); - } - - bool more() - { - return myIterator!=mySet.end(); - } - - const SMDS_MeshElement* next() - { - const SMDS_MeshElement* current=*myIterator; - myIterator++; - return current; - } - }; - return new SMDS_InverseElementIterator(myInverseElements); -} - -SMDS_Iterator * SMDS_MeshNode:: + return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(myInverseElements)); +} + +// Same as GetInverseElementIterator but the create iterator only return +// wanted type elements. +class SMDS_MeshNode_MyIterator:public SMDS_ElemIterator +{ + set mySet; + set::iterator myIterator; + public: + SMDS_MeshNode_MyIterator(SMDSAbs_ElementType type, + const set& s) + { + const SMDS_MeshElement * e; + bool toInsert; + set::iterator it=s.begin(); + while(it!=s.end()) + { + e=*it; + switch(type) + { + case SMDSAbs_Edge: toInsert=true; break; + case SMDSAbs_Face: toInsert=(e->GetType()!=SMDSAbs_Edge); break; + case SMDSAbs_Volume: toInsert=(e->GetType()==SMDSAbs_Volume); break; + } + if(toInsert) mySet.insert(e); + it++; + } + myIterator=mySet.begin(); + } + + bool more() + { + return myIterator!=mySet.end(); + } + + const SMDS_MeshElement* next() + { + const SMDS_MeshElement* current=*myIterator; + myIterator++; + return current; + } +}; + +SMDS_ElemIteratorPtr SMDS_MeshNode:: elementsIterator(SMDSAbs_ElementType type) const { - // Same as GetInverseElementIterator but the create iterator only return - // wanted type elements. - class MyIterator:public SMDS_Iterator - { - set mySet; - set::iterator myIterator; - public: - MyIterator(SMDSAbs_ElementType type, - const set& s) - { - const SMDS_MeshElement * e; - bool toInsert; - set::iterator it=s.begin(); - while(it!=s.end()) - { - e=*it; - switch(type) - { - case SMDSAbs_Edge: toInsert=true; break; - case SMDSAbs_Face: toInsert=(e->GetType()!=SMDSAbs_Edge); break; - case SMDSAbs_Volume: toInsert=(e->GetType()==SMDSAbs_Volume); break; - } - if(toInsert) mySet.insert(e); - it++; - } - myIterator=mySet.begin(); - } - - bool more() - { - return myIterator!=mySet.end(); - } - - const SMDS_MeshElement* next() - { - const SMDS_MeshElement* current=*myIterator; - myIterator++; - return current; - } - }; - - if(type==SMDSAbs_Node) - return SMDS_MeshElement::elementsIterator(SMDSAbs_Node); - else - return new SMDS_IteratorOfElements(this,type, - new MyIterator(type, myInverseElements)); + if(type==SMDSAbs_Node) + return SMDS_MeshElement::elementsIterator(SMDSAbs_Node); + else + return SMDS_ElemIteratorPtr + (new SMDS_IteratorOfElements + (this,type, + SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyIterator(type, myInverseElements)))); } int SMDS_MeshNode::NbNodes() const diff --git a/src/SMDS/SMDS_MeshNode.hxx b/src/SMDS/SMDS_MeshNode.hxx index f53630705..01482f922 100644 --- a/src/SMDS/SMDS_MeshNode.hxx +++ b/src/SMDS/SMDS_MeshNode.hxx @@ -46,22 +46,21 @@ class SMDS_MeshNode:public SMDS_MeshElement void RemoveInverseElement(const SMDS_MeshElement * parent); void ClearInverseElements(); bool emptyInverseElements(); - SMDS_Iterator * GetInverseElementIterator() const; - void SetPosition(SMDS_Position * aPos); - SMDS_Position *GetPosition(); - const SMDS_Position *GetPosition() const; + SMDS_ElemIteratorPtr GetInverseElementIterator() const; + void SetPosition(const SMDS_PositionPtr& aPos); + const SMDS_PositionPtr& GetPosition() const; SMDSAbs_ElementType GetType() const; int NbNodes() const; void setXYZ(double x, double y, double z); friend bool operator<(const SMDS_MeshNode& e1, const SMDS_MeshNode& e2); protected: - SMDS_Iterator * + SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; private: double myX, myY, myZ; - SMDS_Position *myPosition; + SMDS_PositionPtr myPosition; set myInverseElements; }; diff --git a/src/SMDS/SMDS_MeshObject.hxx b/src/SMDS/SMDS_MeshObject.hxx index 7e4bcd464..8386f2115 100644 --- a/src/SMDS/SMDS_MeshObject.hxx +++ b/src/SMDS/SMDS_MeshObject.hxx @@ -29,6 +29,7 @@ class SMDS_MeshObject { - public: + public: + virtual ~SMDS_MeshObject() {} }; #endif diff --git a/src/SMDS/SMDS_Position.cxx b/src/SMDS/SMDS_Position.cxx index 4a9818c56..0a634ceb2 100644 --- a/src/SMDS/SMDS_Position.cxx +++ b/src/SMDS/SMDS_Position.cxx @@ -55,7 +55,3 @@ int SMDS_Position::GetShapeId() const { return myShapeId; } - -SMDS_Position::~SMDS_Position() -{ -} diff --git a/src/SMDS/SMDS_Position.hxx b/src/SMDS/SMDS_Position.hxx index 29a54d82b..6047c30c3 100644 --- a/src/SMDS/SMDS_Position.hxx +++ b/src/SMDS/SMDS_Position.hxx @@ -28,6 +28,10 @@ #define _SMDS_Position_HeaderFile #include "SMDS_TypeOfPosition.hxx" +#include + +class SMDS_Position; +typedef boost::shared_ptr SMDS_PositionPtr; class SMDS_Position { @@ -37,7 +41,7 @@ class SMDS_Position virtual inline SMDS_TypeOfPosition GetTypeOfPosition() const = 0; void SetShapeId(int aShapeId); int GetShapeId() const; - ~SMDS_Position(); + virtual ~SMDS_Position() {} protected: SMDS_Position(int aShapeId); diff --git a/src/SMDS/SMDS_SpacePosition.cxx b/src/SMDS/SMDS_SpacePosition.cxx index 82ef3d54f..7ce582f91 100644 --- a/src/SMDS/SMDS_SpacePosition.cxx +++ b/src/SMDS/SMDS_SpacePosition.cxx @@ -52,8 +52,8 @@ const double * SMDS_SpacePosition::Coords() const return myCoords; } -SMDS_SpacePosition * SMDS_SpacePosition::originSpacePosition() +SMDS_PositionPtr SMDS_SpacePosition::originSpacePosition() { - static SMDS_SpacePosition * staticpos=new SMDS_SpacePosition(); - return staticpos; + static SMDS_PositionPtr staticpos (new SMDS_SpacePosition()); + return staticpos; } diff --git a/src/SMDS/SMDS_SpacePosition.hxx b/src/SMDS/SMDS_SpacePosition.hxx index af995f175..e4fadd6b1 100644 --- a/src/SMDS/SMDS_SpacePosition.hxx +++ b/src/SMDS/SMDS_SpacePosition.hxx @@ -37,8 +37,7 @@ class SMDS_SpacePosition:public SMDS_Position const virtual double * Coords() const; virtual inline SMDS_TypeOfPosition GetTypeOfPosition() const; inline void SetCoords(const double x, const double y, const double z); - ~SMDS_SpacePosition(); - static SMDS_SpacePosition * originSpacePosition(); + static SMDS_PositionPtr originSpacePosition(); private: double myCoords[3]; }; diff --git a/src/SMDS/SMDS_Tria3OfNodes.cxx b/src/SMDS/SMDS_Tria3OfNodes.cxx index c3a96337d..686e34e24 100644 --- a/src/SMDS/SMDS_Tria3OfNodes.cxx +++ b/src/SMDS/SMDS_Tria3OfNodes.cxx @@ -56,42 +56,48 @@ void SMDS_Tria3OfNodes::Print(ostream & OS) const OS << myNodes[i] << ") " << endl; } -SMDS_Iterator * SMDS_Tria3OfNodes:: - elementsIterator(SMDSAbs_ElementType type) const +class SMDS_Tria3OfNodes_MyIterator:public SMDS_ElemIterator { - class MyIterator:public SMDS_Iterator - { - const SMDS_MeshNode * const* mySet; - int index; - public: - MyIterator(const SMDS_MeshNode * const* s):mySet(s),index(0) - {} + const SMDS_MeshNode * const* mySet; + int index; + public: + SMDS_Tria3OfNodes_MyIterator(const SMDS_MeshNode * const* s): + mySet(s),index(0) {} - bool more() - { - return index<3; - } + bool more() + { + return index<3; + } - const SMDS_MeshElement* next() - { - index++; - return mySet[index-1]; - } - }; + const SMDS_MeshElement* next() + { + index++; + return mySet[index-1]; + } +}; - switch(type) - { - case SMDSAbs_Face:return SMDS_MeshElement::elementsIterator(SMDSAbs_Face); - case SMDSAbs_Node:return new MyIterator(myNodes); - case SMDSAbs_Edge: - MESSAGE("Error : edge iterator for SMDS_FaceOfNodes not implemented"); - break; - default:return new SMDS_IteratorOfElements(this,type,new MyIterator(myNodes)); - } +SMDS_ElemIteratorPtr SMDS_Tria3OfNodes:: + elementsIterator(SMDSAbs_ElementType type) const +{ + switch(type) + { + case SMDSAbs_Face: + return SMDS_MeshElement::elementsIterator(SMDSAbs_Face); + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new SMDS_Tria3OfNodes_MyIterator(myNodes)); + case SMDSAbs_Edge: + MESSAGE("Error : edge iterator for SMDS_FaceOfNodes not implemented"); + break; + default: + return SMDS_ElemIteratorPtr + (new SMDS_IteratorOfElements + (this,type,SMDS_ElemIteratorPtr(new SMDS_Tria3OfNodes_MyIterator(myNodes)))); + } } -SMDS_Tria3OfNodes::SMDS_Tria3OfNodes(SMDS_MeshNode* node1, SMDS_MeshNode* node2, - SMDS_MeshNode* node3) +SMDS_Tria3OfNodes::SMDS_Tria3OfNodes(const SMDS_MeshNode* node1, + const SMDS_MeshNode* node2, + const SMDS_MeshNode* node3) { myNodes[0]=node1; myNodes[1]=node2; diff --git a/src/SMDS/SMDS_Tria3OfNodes.hxx b/src/SMDS/SMDS_Tria3OfNodes.hxx index ee4c330da..63552a03d 100644 --- a/src/SMDS/SMDS_Tria3OfNodes.hxx +++ b/src/SMDS/SMDS_Tria3OfNodes.hxx @@ -31,14 +31,15 @@ class SMDS_Tria3OfNodes:public SMDS_MeshFace { public: void Print(ostream & OS) const; - SMDS_Tria3OfNodes(SMDS_MeshNode* node1, SMDS_MeshNode* node2, - SMDS_MeshNode* node3); + SMDS_Tria3OfNodes(const SMDS_MeshNode* node1, + const SMDS_MeshNode* node2, + const SMDS_MeshNode* node3); int NbEdges() const; int NbFaces() const; int NbNodes() const; protected: - SMDS_Iterator * + SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; private: diff --git a/src/SMDS/SMDS_VertexPosition.hxx b/src/SMDS/SMDS_VertexPosition.hxx index 6fc5a3c61..52ef05918 100644 --- a/src/SMDS/SMDS_VertexPosition.hxx +++ b/src/SMDS/SMDS_VertexPosition.hxx @@ -36,7 +36,6 @@ class SMDS_VertexPosition:public SMDS_Position SMDS_TypeOfPosition GetTypeOfPosition() const; SMDS_VertexPosition(int aVertexId=0); const double *Coords() const; - ~SMDS_VertexPosition(); }; #endif diff --git a/src/SMDS/SMDS_VolumeOfFaces.cxx b/src/SMDS/SMDS_VolumeOfFaces.cxx index c221452ba..435107fe7 100644 --- a/src/SMDS/SMDS_VolumeOfFaces.cxx +++ b/src/SMDS/SMDS_VolumeOfFaces.cxx @@ -21,7 +21,7 @@ // // // -// File : SMDS_MeshVolume.cxx +// File : SMDS_VolumeOfFaces.cxx // Author : Jean-Michel BOULCOURT // Module : SMESH @@ -46,39 +46,46 @@ int SMDS_VolumeOfFaces::NbFaces() const return myFaces.size(); } -SMDS_Iterator * SMDS_VolumeOfFaces:: - elementsIterator(SMDSAbs_ElementType type) const +class SMDS_VolumeOfFaces_MyIterator:public SMDS_ElemIterator { - class MyIterator:public SMDS_Iterator - { - const vector& mySet; - int index; - public: - MyIterator(const vector& s):mySet(s),index(0) - {} + const vector& mySet; + int index; + public: + SMDS_VolumeOfFaces_MyIterator(const vector& s): + mySet(s),index(0) {} - bool more() - { - return index * + SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; - vector myFaces; + vector myFaces; }; #endif diff --git a/src/SMDS/SMDS_VolumeOfNodes.cxx b/src/SMDS/SMDS_VolumeOfNodes.cxx index b2a7a547d..3f4d6a245 100644 --- a/src/SMDS/SMDS_VolumeOfNodes.cxx +++ b/src/SMDS/SMDS_VolumeOfNodes.cxx @@ -28,14 +28,14 @@ /// 5,1 and 7,3 are an edges. /////////////////////////////////////////////////////////////////////////////// SMDS_VolumeOfNodes::SMDS_VolumeOfNodes( - SMDS_MeshNode * node1, - SMDS_MeshNode * node2, - SMDS_MeshNode * node3, - SMDS_MeshNode * node4, - SMDS_MeshNode * node5, - SMDS_MeshNode * node6, - SMDS_MeshNode * node7, - SMDS_MeshNode * node8) + const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4, + const SMDS_MeshNode * node5, + const SMDS_MeshNode * node6, + const SMDS_MeshNode * node7, + const SMDS_MeshNode * node8) { myNodes.resize(8); myNodes[0]=node1; @@ -49,10 +49,10 @@ SMDS_VolumeOfNodes::SMDS_VolumeOfNodes( } SMDS_VolumeOfNodes::SMDS_VolumeOfNodes( - SMDS_MeshNode * node1, - SMDS_MeshNode * node2, - SMDS_MeshNode * node3, - SMDS_MeshNode * node4) + const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4) { myNodes.resize(4); myNodes[0]=node1; @@ -62,11 +62,11 @@ SMDS_VolumeOfNodes::SMDS_VolumeOfNodes( } SMDS_VolumeOfNodes::SMDS_VolumeOfNodes( - SMDS_MeshNode * node1, - SMDS_MeshNode * node2, - SMDS_MeshNode * node3, - SMDS_MeshNode * node4, - SMDS_MeshNode * node5) + const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4, + const SMDS_MeshNode * node5) { myNodes.resize(5); myNodes[0]=node1; @@ -77,12 +77,12 @@ SMDS_VolumeOfNodes::SMDS_VolumeOfNodes( } SMDS_VolumeOfNodes::SMDS_VolumeOfNodes( - SMDS_MeshNode * node1, - SMDS_MeshNode * node2, - SMDS_MeshNode * node3, - SMDS_MeshNode * node4, - SMDS_MeshNode * node5, - SMDS_MeshNode * node6) + const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4, + const SMDS_MeshNode * node5, + const SMDS_MeshNode * node6) { myNodes.resize(6); myNodes[0]=node1; @@ -134,34 +134,39 @@ int SMDS_VolumeOfNodes::NbEdges() const } } -SMDS_Iterator * SMDS_VolumeOfNodes:: - elementsIterator(SMDSAbs_ElementType type) const +class SMDS_VolumeOfNodes_MyIterator:public SMDS_ElemIterator { - class MyIterator:public SMDS_Iterator - { - const vector& mySet; - int index; - public: - MyIterator(const vector& s):mySet(s),index(0) - {} + const vector& mySet; + int index; + public: + SMDS_VolumeOfNodes_MyIterator(const vector& s): + mySet(s),index(0) {} - bool more() - { - return index * + SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; vector myNodes; }; diff --git a/src/SMESHDS/Makefile.in b/src/SMESHDS/Makefile.in index bc62fc4ca..2b4d5391e 100644 --- a/src/SMESHDS/Makefile.in +++ b/src/SMESHDS/Makefile.in @@ -42,7 +42,8 @@ LIB_SRC = \ SMESHDS_Script.cxx \ SMESHDS_Command.cxx \ SMESHDS_SubMesh.cxx \ - SMESHDS_Mesh.cxx + SMESHDS_Mesh.cxx \ + SMESHDS_Group.cxx LIB_CLIENT_IDL = LIB_SERVER_IDL = @@ -61,10 +62,11 @@ EXPORT_HEADERS= \ SMESHDS_Script.hxx \ SMESHDS_Command.hxx \ SMESHDS_CommandType.hxx \ - SMESHDS_SubMesh.hxx + SMESHDS_SubMesh.hxx \ + SMESHDS_Group.hxx # additionnal information to compil and link file -CPPFLAGS += $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome +CPPFLAGS += $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS) CXXFLAGS += $(OCC_CXXFLAGS) -I${KERNEL_ROOT_DIR}/include/salome LDFLAGS += $(OCC_KERNEL_LIBS) diff --git a/src/SMESHDS/SMESHDS_Command.hxx b/src/SMESHDS/SMESHDS_Command.hxx index 5de4a710c..7c3014e7d 100644 --- a/src/SMESHDS/SMESHDS_Command.hxx +++ b/src/SMESHDS/SMESHDS_Command.hxx @@ -29,7 +29,6 @@ #include "SMESHDS_CommandType.hxx" #include -using namespace std; class SMESHDS_Command { diff --git a/src/SMESHDS/SMESHDS_CommandType.hxx b/src/SMESHDS/SMESHDS_CommandType.hxx index 404642e87..fd64ba005 100644 --- a/src/SMESHDS/SMESHDS_CommandType.hxx +++ b/src/SMESHDS/SMESHDS_CommandType.hxx @@ -38,8 +38,7 @@ SMESHDS_AddPrism, SMESHDS_AddHexahedron, SMESHDS_RemoveNode, SMESHDS_RemoveElement, -SMESHDS_MoveNode, -SMESHDS_UpdateAll +SMESHDS_MoveNode }; diff --git a/src/SMESHDS/SMESHDS_Group.cxx b/src/SMESHDS/SMESHDS_Group.cxx new file mode 100644 index 000000000..29d7db4f4 --- /dev/null +++ b/src/SMESHDS/SMESHDS_Group.cxx @@ -0,0 +1,129 @@ +// SMESH SMESHDS : idl implementation based on 'SMESH' unit's classes +// +// Copyright (C) 2004 CEA +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESHDS_Group.cxx +// Author : Michael Sazonov, OCC +// Module : SMESH +// $Header$ + +#include +#include + +//============================================================================= +/*! + * + */ +//============================================================================= + +SMESHDS_Group::SMESHDS_Group (const SMESHDS_Mesh* theMesh, + const SMDSAbs_ElementType theType) + : SMDS_MeshGroup(theMesh,theType), myStoreName(""), + myCurIndex(0), myCurID(0) +{ +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool SMESHDS_Group::Contains (const int theID) const +{ + const SMDS_MeshElement* aElem = findInMesh (theID); + if (aElem) + return SMDS_MeshGroup::Contains(aElem); + return false; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool SMESHDS_Group::Add (const int theID) +{ + const SMDS_MeshElement* aElem = findInMesh (theID); + if (!aElem || SMDS_MeshGroup::Contains(aElem)) + return false; + SMDS_MeshGroup::Add (aElem); + return true; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool SMESHDS_Group::Remove (const int theID) +{ + const SMDS_MeshElement* aElem = findInMesh (theID); + if (!aElem || !SMDS_MeshGroup::Contains(aElem)) + return false; + SMDS_MeshGroup::Remove (aElem); + return true; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +int SMESHDS_Group::GetID (const int theIndex) +{ + if (theIndex < 1 || theIndex > Extent()) + return -1; + if (myCurIndex < 1 || myCurIndex > theIndex) { + InitIterator(); + myCurIndex = 0; + myCurID = -1; + } + while (myCurIndex < theIndex && More()) { + myCurIndex++; + myCurID = Next()->GetID(); + } + return myCurID; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +const SMDS_MeshElement* SMESHDS_Group::findInMesh (const int theID) const +{ + SMDSAbs_ElementType aType = GetType(); + const SMDS_MeshElement* aElem = NULL; + if (aType == SMDSAbs_Node) { + aElem = GetMesh()->FindNode(theID); + } + else if (aType != SMDSAbs_All) { + aElem = GetMesh()->FindElement(theID); + if (aElem && aType != aElem->GetType()) + aElem = NULL; + } + return aElem; +} diff --git a/src/SMESHDS/SMESHDS_Group.hxx b/src/SMESHDS/SMESHDS_Group.hxx new file mode 100644 index 000000000..444914cee --- /dev/null +++ b/src/SMESHDS/SMESHDS_Group.hxx @@ -0,0 +1,72 @@ +// SMESH SMESHDS : management of mesh data and SMESH document +// +// Copyright (C) 2004 CEA +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESHDS_Group.hxx +// Author : Michael Sazonov (OCC) +// Module : SMESH +// $Header$ + +#ifndef _SMESHDS_Group_HeaderFile +#define _SMESHDS_Group_HeaderFile + +#include +#include + +class SMESHDS_Mesh; + +class SMESHDS_Group : public SMDS_MeshGroup +{ + public: + + SMESHDS_Group (const SMESHDS_Mesh* theMesh, + const SMDSAbs_ElementType theType); + + void SetStoreName (const char* theName) + { myStoreName = theName; } + + const char* GetStoreName () const + { return myStoreName.c_str(); } + + bool Contains (const int theID) const; + + bool Add (const int theID); + bool Remove (const int theID); + + int GetID (const int theIndex); + // use it for iterations 1..Extent() as alternative to parent's + // InitIterator(), More(), Next() + + private: + SMESHDS_Group (const SMESHDS_Group& theOther); + // prohibited copy constructor + SMESHDS_Group& operator = (const SMESHDS_Group& theOther); + // prohibited assign operator + + const SMDS_MeshElement* findInMesh (const int theID) const; + + string myStoreName; + int myCurIndex; + int myCurID; + +}; + +#endif diff --git a/src/SMESHDS/SMESHDS_Hypothesis.cxx b/src/SMESHDS/SMESHDS_Hypothesis.cxx index bb5047403..b1cf717b8 100644 --- a/src/SMESHDS/SMESHDS_Hypothesis.cxx +++ b/src/SMESHDS/SMESHDS_Hypothesis.cxx @@ -97,7 +97,3 @@ int SMESHDS_Hypothesis::GetType() const return _type; } -void SMESHDS_Hypothesis::SetID(int id) -{ - _hypId=id; -} \ No newline at end of file diff --git a/src/SMESHDS/SMESHDS_Hypothesis.hxx b/src/SMESHDS/SMESHDS_Hypothesis.hxx index b5c414a25..3a79039b8 100644 --- a/src/SMESHDS/SMESHDS_Hypothesis.hxx +++ b/src/SMESHDS/SMESHDS_Hypothesis.hxx @@ -48,7 +48,6 @@ public: const char* GetName() const; int GetID() const; - void SetID(int id); int GetType() const; virtual ostream & SaveTo(ostream & save)=0; diff --git a/src/SMESHDS/SMESHDS_Mesh.cxx b/src/SMESHDS/SMESHDS_Mesh.cxx index 4aafa43ad..a6cae5391 100644 --- a/src/SMESHDS/SMESHDS_Mesh.cxx +++ b/src/SMESHDS/SMESHDS_Mesh.cxx @@ -100,11 +100,16 @@ bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape & S, //function : AddNode //purpose : //======================================================================= -SMDS_MeshNode* SMESHDS_Mesh::AddNode(double x, double y, double z) -{ - SMDS_MeshNode* node = SMDS_Mesh::AddNode(x, y, z); - if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z); - return node; +SMDS_MeshNode* SMESHDS_Mesh::AddNode(double x, double y, double z){ + SMDS_MeshNode* node = SMDS_Mesh::AddNode(x, y, z); + if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z); + return node; +} + +SMDS_MeshNode* SMESHDS_Mesh::AddNodeWithID(double x, double y, double z, int ID){ + SMDS_MeshNode* node = SMDS_Mesh::AddNodeWithID(x,y,z,ID); + if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z); + return node; } //======================================================================= @@ -113,137 +118,345 @@ SMDS_MeshNode* SMESHDS_Mesh::AddNode(double x, double y, double z) //======================================================================= void SMESHDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z) { - SMDS_MeshNode * node=const_cast(n); - node->setXYZ(x,y,z); - myScript->MoveNode(n->GetID(), x, y, z); + SMDS_MeshNode * node=const_cast(n); + node->setXYZ(x,y,z); + myScript->MoveNode(n->GetID(), x, y, z); } //======================================================================= //function : AddEdge //purpose : //======================================================================= +SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int ID) +{ + SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,ID); + if(anElem) myScript->AddEdge(ID,n1,n2); + return anElem; +} + +SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + int ID) +{ + return AddEdgeWithID(n1->GetID(), + n2->GetID(), + ID); +} + SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2) + const SMDS_MeshNode * n2) { - SMDS_MeshEdge* e = SMDS_Mesh::AddEdge(n1,n2); - if(e!=NULL) myScript->AddEdge(e->GetID(), n1->GetID(), n2->GetID()); - return e; + SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2); + if(anElem) myScript->AddEdge(anElem->GetID(), + n1->GetID(), + n2->GetID()); + return anElem; } //======================================================================= //function :AddFace //purpose : //======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int ID) +{ + SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, ID); + if(anElem) myScript->AddFace(ID,n1,n2,n3); + return anElem; +} + +SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + int ID) +{ + return AddFaceWithID(n1->GetID(), + n2->GetID(), + n3->GetID(), + ID); +} + SMDS_MeshFace* SMESHDS_Mesh::AddFace( const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3) { - SMDS_MeshFace *f = SMDS_Mesh::AddFace(n1, n2, n3); - if(f!=NULL) myScript->AddFace(f->GetID(), n1->GetID(), n2->GetID(), - n3->GetID()); - return f; + SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3); + if(anElem) myScript->AddFace(anElem->GetID(), + n1->GetID(), + n2->GetID(), + n3->GetID()); + return anElem; } //======================================================================= //function :AddFace //purpose : //======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, int ID) +{ + SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, n4, ID); + if(anElem) myScript->AddFace(ID, n1, n2, n3, n4); + return anElem; +} + +SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + int ID) +{ + return AddFaceWithID(n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID(), + ID); +} + SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4) { - SMDS_MeshFace *f = SMDS_Mesh::AddFace(n1, n2, n3, n4); - if(f!=NULL) - myScript->AddFace(f->GetID(), n1->GetID(), n2->GetID(), n3->GetID(), - n4->GetID()); - return f; + SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3, n4); + if(anElem) myScript->AddFace(anElem->GetID(), + n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID()); + return anElem; } //======================================================================= //function :AddVolume //purpose : //======================================================================= -SMDS_MeshVolume* SMESHDS_Mesh::AddVolume( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4) +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int ID) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID); + if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4); + return anElem; +} + +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + int ID) +{ + return AddVolumeWithID(n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID(), + ID); +} + +SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4) { - SMDS_MeshVolume *f = SMDS_Mesh::AddVolume(n1, n2, n3, n4); - if(f!=NULL) - myScript->AddVolume(f->GetID(), n1->GetID(), n2->GetID(), n3->GetID(), - n4->GetID()); - return f; + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4); + if(anElem) myScript->AddVolume(anElem->GetID(), + n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID()); + return anElem; } //======================================================================= //function :AddVolume //purpose : //======================================================================= -SMDS_MeshVolume* SMESHDS_Mesh::AddVolume( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5) +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int ID) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID); + if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5); + return anElem; +} + +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + int ID) +{ + return AddVolumeWithID(n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID(), + n5->GetID(), + ID); +} + +SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5) { - SMDS_MeshVolume *v = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5); - if(v!=NULL) - myScript->AddVolume(v->GetID(), n1->GetID(), n2->GetID(), n3->GetID(), - n4->GetID(), n5->GetID()); - return v; + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5); + if(anElem) myScript->AddVolume(anElem->GetID(), + n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID(), + n5->GetID()); + return anElem; } //======================================================================= //function :AddVolume //purpose : //======================================================================= -SMDS_MeshVolume* SMESHDS_Mesh::AddVolume( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6) +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int ID) { - SMDS_MeshVolume *v= SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6); - if(v!=NULL) - myScript->AddVolume(v->GetID(), n1->GetID(), n2->GetID(), n3->GetID(), - n4->GetID(), n5->GetID(), n6->GetID()); - return v; + SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID); + if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6); + return anElem; +} + +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + int ID) +{ + return AddVolumeWithID(n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID(), + n5->GetID(), + n6->GetID(), + ID); +} + +SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6); + if(anElem) myScript->AddVolume(anElem->GetID(), + n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID(), + n5->GetID(), + n6->GetID()); + return anElem; } //======================================================================= //function :AddVolume //purpose : //======================================================================= -SMDS_MeshVolume* SMESHDS_Mesh::AddVolume( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, - const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8) -{ - SMDS_MeshVolume *v= - SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8); - if(v!=NULL) - myScript->AddVolume(v->GetID(), n1->GetID(), n2->GetID(), n3->GetID(), - n4->GetID(), n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID()); - return v; -} - +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int ID) +{ + SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID); + if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6, n7, n8); + return anElem; +} + +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + int ID) +{ + return AddVolumeWithID(n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID(), + n5->GetID(), + n6->GetID(), + n7->GetID(), + n8->GetID(), + ID); +} + +SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8); + if(anElem) myScript->AddVolume(anElem->GetID(), + n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID(), + n5->GetID(), + n6->GetID(), + n7->GetID(), + n8->GetID()); + return anElem; +} +//======================================================================= +//function : removeFromSubMeshes +//purpose : +//======================================================================= + +static void removeFromSubMeshes (map & theSubMeshes, + list & theElems, + const bool isNode) +{ + if ( theElems.empty() ) + return; + + map::iterator SubIt = theSubMeshes.begin(); + for ( ; SubIt != theSubMeshes.end(); SubIt++ ) + { + list::iterator elIt = theElems.begin(); + while ( elIt != theElems.end() ) + { + bool removed = false; + if ( isNode ) + removed = (*SubIt).second->RemoveNode( static_cast (*elIt) ); + else + removed = (*SubIt).second->RemoveElement( *elIt ); + + if (removed) + { + elIt = theElems.erase( elIt ); + if ( theElems.empty() ) + return; // all elements are found and removed + } + else + { + elIt++ ; + } + } + } +} + //======================================================================= //function : RemoveNode //purpose : //======================================================================= void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n) { - SMDS_Mesh::RemoveNode(n); - myScript->RemoveNode(n->GetID()); + myScript->RemoveNode(n->GetID()); + + list removedElems; + list removedNodes; + + SMDS_Mesh::RemoveElement( n, removedElems, removedNodes, true ); + + removeFromSubMeshes( myShapeIndexToSubMesh, removedElems, false ); + removeFromSubMeshes( myShapeIndexToSubMesh, removedNodes, true ); } //======================================================================= @@ -252,8 +465,20 @@ void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n) //======================================================================== void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt) { - SMDS_Mesh::RemoveElement(elt); - myScript->RemoveElement(elt->GetID()); + if (elt->GetType() == SMDSAbs_Node) + { + RemoveNode( static_cast( elt )); + return; + } + + myScript->RemoveElement(elt->GetID()); + + list removedElems; + list removedNodes; + + SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes, false); + + removeFromSubMeshes( myShapeIndexToSubMesh, removedElems, false ); } //======================================================================= @@ -291,7 +516,7 @@ void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode * aNode, int Index = myIndexToShape.FindIndex(S); //Set Position on Node - aNode->SetPosition(new SMDS_FacePosition(Index, 0., 0.)); + aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(Index, 0., 0.))); //Update or build submesh map::iterator it=myShapeIndexToSubMesh.find(Index); @@ -313,7 +538,7 @@ void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode * aNode, int Index = myIndexToShape.FindIndex(S); //Set Position on Node - aNode->SetPosition(new SMDS_EdgePosition(Index, 0.)); + aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(Index, 0.))); //Update or build submesh map::iterator it=myShapeIndexToSubMesh.find(Index); @@ -335,7 +560,7 @@ void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode * aNode, int Index = myIndexToShape.FindIndex(S); //Set Position on Node - aNode->SetPosition(new SMDS_VertexPosition(Index)); + aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index))); //Update or build submesh map::iterator it=myShapeIndexToSubMesh.find(Index); @@ -402,13 +627,40 @@ TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const /////////////////////////////////////////////////////////////////////////////// SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S) { - if (myShape.IsNull()) MESSAGE("myShape is NULL"); + if (myShape.IsNull()) MESSAGE("myShape is NULL"); - int Index = myIndexToShape.FindIndex(S); - if (myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end()) - return myShapeIndexToSubMesh[Index]; - else - return NULL; + int Index = myIndexToShape.FindIndex(S); + if (myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end()) + return myShapeIndexToSubMesh[Index]; + else + return NULL; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Return the sub mesh by Id of shape it is linked to +/////////////////////////////////////////////////////////////////////////////// +SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index) +{ + if (myShape.IsNull()) MESSAGE("myShape is NULL"); + + if (myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end()) + return myShapeIndexToSubMesh[Index]; + else + return NULL; +} + +//======================================================================= +//function : SubMeshIndices +//purpose : +//======================================================================= +list SMESHDS_Mesh::SubMeshIndices() +{ + list anIndices; + std::map::iterator anIter = myShapeIndexToSubMesh.begin(); + for (; anIter != myShapeIndexToSubMesh.end(); anIter++) { + anIndices.push_back((*anIter).first); + } + return anIndices; } //======================================================================= @@ -520,7 +772,7 @@ void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index) void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index) { //Set Position on Node - aNode->SetPosition(new SMDS_FacePosition(Index, 0., 0.)); + aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(Index, 0., 0.))); //Update or build submesh if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end()) @@ -536,7 +788,7 @@ void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index) void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode, int Index) { //Set Position on Node - aNode->SetPosition(new SMDS_EdgePosition(Index, 0.)); + aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(Index, 0.))); //Update or build submesh if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end()) @@ -552,7 +804,7 @@ void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode, int Index) void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index) { //Set Position on Node - aNode->SetPosition(new SMDS_VertexPosition(Index)); + aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index))); //Update or build submesh if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end()) @@ -577,12 +829,3 @@ void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement, SMESHDS_Mesh::~SMESHDS_Mesh() { } - -/** - * Add FULL_UPDATE command to the log of this mesh. Once interpreted by the - * graphical client it will (re)draw the full mesh. - */ -void SMESHDS_Mesh::logFullUpdate() -{ - myScript->UpdateAll(); -} diff --git a/src/SMESHDS/SMESHDS_Mesh.hxx b/src/SMESHDS/SMESHDS_Mesh.hxx index 2f3766155..7d26b2266 100644 --- a/src/SMESHDS/SMESHDS_Mesh.hxx +++ b/src/SMESHDS/SMESHDS_Mesh.hxx @@ -49,103 +49,158 @@ #include #else #include - using namespace __gnu_cxx; + namespace gstd = __gnu_cxx; #endif #endif -using namespace std; - -class SMESHDS_Mesh:public SMDS_Mesh -{ - - public: - - SMESHDS_Mesh(int MeshID); - void ShapeToMesh(const TopoDS_Shape & S); - bool AddHypothesis(const TopoDS_Shape & SS, const SMESHDS_Hypothesis * H); - bool RemoveHypothesis(const TopoDS_Shape & S, const SMESHDS_Hypothesis * H); - SMDS_MeshNode * AddNode(double x, double y, double z); - void RemoveNode(const SMDS_MeshNode *); - void MoveNode(const SMDS_MeshNode *, double x, double y, double z); - SMDS_MeshEdge* AddEdge( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2); - SMDS_MeshFace* AddFace( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3); - SMDS_MeshFace* AddFace( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4); - SMDS_MeshVolume* AddVolume( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4); - SMDS_MeshVolume* AddVolume( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5); - SMDS_MeshVolume* AddVolume( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6); - SMDS_MeshVolume* AddVolume( - const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, - const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8); - - void RemoveElement(const SMDS_MeshElement *); - void SetNodeInVolume(SMDS_MeshNode * aNode, const TopoDS_Shell & S); - void SetNodeOnFace(SMDS_MeshNode * aNode, const TopoDS_Face & S); - void SetNodeOnEdge(SMDS_MeshNode * aNode, const TopoDS_Edge & S); - void SetNodeOnVertex(SMDS_MeshNode * aNode, const TopoDS_Vertex & S); - void UnSetNodeOnShape(const SMDS_MeshNode * aNode); - void SetMeshElementOnShape(const SMDS_MeshElement * anElt, - const TopoDS_Shape & S); - void UnSetMeshElementOnShape(const SMDS_MeshElement * anElt, - const TopoDS_Shape & S); - TopoDS_Shape ShapeToMesh() const; - bool HasMeshElements(const TopoDS_Shape & S); - SMESHDS_SubMesh * MeshElements(const TopoDS_Shape & S); - bool HasHypothesis(const TopoDS_Shape & S); - const list& GetHypothesis(const TopoDS_Shape & S) const; - SMESHDS_Script * GetScript(); - void ClearScript(); - int ShapeToIndex(const TopoDS_Shape & aShape); - TopoDS_Shape IndexToShape(int ShapeIndex); - void NewSubMesh(int Index); - void SetNodeInVolume(const SMDS_MeshNode * aNode, int Index); - void SetNodeOnFace(SMDS_MeshNode * aNode, int Index); - void SetNodeOnEdge(SMDS_MeshNode * aNode, int Index); - void SetNodeOnVertex(SMDS_MeshNode * aNode, int Index); - void SetMeshElementOnShape(const SMDS_MeshElement * anElt, int Index); - ~SMESHDS_Mesh(); - void logFullUpdate(); - - private: - struct HashTopoDS_Shape - { - size_t operator()(const TopoDS_Shape& S) const {return S.HashCode(2147483647);} - }; - typedef hash_map,HashTopoDS_Shape > ShapeToHypothesis; - int myMeshID; - TopoDS_Shape myShape; - TopTools_IndexedMapOfShape myIndexToShape; - map myShapeIndexToSubMesh; - ShapeToHypothesis myShapeToHypothesis; - SMESHDS_Script * myScript; +class SMESHDS_Mesh:public SMDS_Mesh{ +public: + SMESHDS_Mesh(int MeshID); + void ShapeToMesh(const TopoDS_Shape & S); + bool AddHypothesis(const TopoDS_Shape & SS, const SMESHDS_Hypothesis * H); + bool RemoveHypothesis(const TopoDS_Shape & S, const SMESHDS_Hypothesis * H); + + virtual SMDS_MeshNode* AddNodeWithID(double x, double y, double z, int ID); + virtual SMDS_MeshNode * AddNode(double x, double y, double z); + + virtual SMDS_MeshEdge* AddEdgeWithID(int n1, int n2, int ID); + virtual SMDS_MeshEdge* AddEdgeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + int ID); + virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2); + + virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int ID); + virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + int ID); + virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3); + + virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4, int ID); + virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + int ID); + virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4); + + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4); + + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5); + + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6); + + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8); + + void MoveNode(const SMDS_MeshNode *, double x, double y, double z); + virtual void RemoveNode(const SMDS_MeshNode *); + void RemoveElement(const SMDS_MeshElement *); + + void SetNodeInVolume(SMDS_MeshNode * aNode, const TopoDS_Shell & S); + void SetNodeOnFace(SMDS_MeshNode * aNode, const TopoDS_Face & S); + void SetNodeOnEdge(SMDS_MeshNode * aNode, const TopoDS_Edge & S); + void SetNodeOnVertex(SMDS_MeshNode * aNode, const TopoDS_Vertex & S); + void UnSetNodeOnShape(const SMDS_MeshNode * aNode); + void SetMeshElementOnShape(const SMDS_MeshElement * anElt, + const TopoDS_Shape & S); + void UnSetMeshElementOnShape(const SMDS_MeshElement * anElt, + const TopoDS_Shape & S); + TopoDS_Shape ShapeToMesh() const; + bool HasMeshElements(const TopoDS_Shape & S); + SMESHDS_SubMesh * MeshElements(const TopoDS_Shape & S); + SMESHDS_SubMesh * MeshElements(const int Index); + list SubMeshIndices(); + const std::map& SubMeshes() + { return myShapeIndexToSubMesh; } + + bool HasHypothesis(const TopoDS_Shape & S); + const list& GetHypothesis(const TopoDS_Shape & S) const; + SMESHDS_Script * GetScript(); + void ClearScript(); + int ShapeToIndex(const TopoDS_Shape & aShape); + TopoDS_Shape IndexToShape(int ShapeIndex); + + void NewSubMesh(int Index); + void SetNodeInVolume(const SMDS_MeshNode * aNode, int Index); + void SetNodeOnFace(SMDS_MeshNode * aNode, int Index); + void SetNodeOnEdge(SMDS_MeshNode * aNode, int Index); + void SetNodeOnVertex(SMDS_MeshNode * aNode, int Index); + void SetMeshElementOnShape(const SMDS_MeshElement * anElt, int Index); + + ~SMESHDS_Mesh(); + +private: + struct HashTopoDS_Shape{ + size_t operator()(const TopoDS_Shape& S) const { + return S.HashCode(2147483647); + } + }; + typedef std::list THypList; + typedef gstd::hash_map ShapeToHypothesis; + ShapeToHypothesis myShapeToHypothesis; + + int myMeshID; + TopoDS_Shape myShape; + TopTools_IndexedMapOfShape myIndexToShape; + std::map myShapeIndexToSubMesh; + SMESHDS_Script* myScript; }; + + #endif diff --git a/src/SMESHDS/SMESHDS_Script.cxx b/src/SMESHDS/SMESHDS_Script.cxx index cc969b748..57baf301c 100644 --- a/src/SMESHDS/SMESHDS_Script.cxx +++ b/src/SMESHDS/SMESHDS_Script.cxx @@ -26,6 +26,7 @@ // Module : SMESH // $Header: +using namespace std; #include "SMESHDS_Script.hxx" //======================================================================= @@ -320,12 +321,3 @@ const list& SMESHDS_Script::GetCommands() { return myCommands; } - -/** - * Add UpdateAll command to the log of this mesh. Once interpreted by the - * graphical client it will (re)draw the full mesh. - */ -void SMESHDS_Script::UpdateAll() -{ - myCommands.insert(myCommands.end(), new SMESHDS_Command(SMESHDS_UpdateAll)); -} diff --git a/src/SMESHDS/SMESHDS_Script.hxx b/src/SMESHDS/SMESHDS_Script.hxx index 70d4d5b30..8a67c98fe 100644 --- a/src/SMESHDS/SMESHDS_Script.hxx +++ b/src/SMESHDS/SMESHDS_Script.hxx @@ -52,7 +52,6 @@ class SMESHDS_Script void RemoveElement(int ElementID); void Clear(); const list & GetCommands(); - void UpdateAll(); ~SMESHDS_Script(); private: diff --git a/src/SMESHDS/SMESHDS_SubMesh.cxx b/src/SMESHDS/SMESHDS_SubMesh.cxx index 31710630d..c7ad4c210 100644 --- a/src/SMESHDS/SMESHDS_SubMesh.cxx +++ b/src/SMESHDS/SMESHDS_SubMesh.cxx @@ -42,9 +42,12 @@ void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * ME) //function : RemoveElement //purpose : //======================================================================= -void SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME) +bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME) { - myElements.erase(ME); + if ( NbElements() ) + return myElements.erase(ME); + + return false; } //======================================================================= @@ -60,9 +63,12 @@ void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N) //function : RemoveNode //purpose : //======================================================================= -void SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N) +bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N) { - myNodes.erase(N); + if ( NbNodes() ) + return myNodes.erase(N); + + return false; } //======================================================================= @@ -85,8 +91,9 @@ int SMESHDS_SubMesh::NbNodes() const template class MySetIterator:public SMDS_Iterator { - const set& mySet; - set::const_iterator myIt; + typedef const set TSet; + typename TSet::const_iterator myIt; + TSet& mySet; public: MySetIterator(const set& s):mySet(s), myIt(s.begin()) @@ -108,17 +115,17 @@ template class MySetIterator:public SMDS_Iterator ///Return an iterator on the elements of submesh ///The created iterator must be free by the caller /////////////////////////////////////////////////////////////////////////////// -SMDS_Iterator * SMESHDS_SubMesh::GetElements() const +SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements() const { - return new MySetIterator(myElements); + return SMDS_ElemIteratorPtr(new MySetIterator(myElements)); } /////////////////////////////////////////////////////////////////////////////// ///Return an iterator on the nodes of submesh ///The created iterator must be free by the caller /////////////////////////////////////////////////////////////////////////////// -SMDS_Iterator * SMESHDS_SubMesh::GetNodes() const +SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const { - return new MySetIterator(myNodes); + return SMDS_NodeIteratorPtr(new MySetIterator(myNodes)); } diff --git a/src/SMESHDS/SMESHDS_SubMesh.hxx b/src/SMESHDS/SMESHDS_SubMesh.hxx index bda8f04bb..be7e7462a 100644 --- a/src/SMESHDS/SMESHDS_SubMesh.hxx +++ b/src/SMESHDS/SMESHDS_SubMesh.hxx @@ -36,13 +36,13 @@ class SMESHDS_SubMesh { public: void AddElement(const SMDS_MeshElement * ME); - void RemoveElement(const SMDS_MeshElement * ME); + bool RemoveElement(const SMDS_MeshElement * ME); // ret true if ME was in void AddNode(const SMDS_MeshNode * ME); - void RemoveNode(const SMDS_MeshNode * ME); + bool RemoveNode(const SMDS_MeshNode * ME); // ret true if ME was in int NbElements() const; - SMDS_Iterator * GetElements() const; + SMDS_ElemIteratorPtr GetElements() const; int NbNodes() const; - SMDS_Iterator * GetNodes() const; + SMDS_NodeIteratorPtr GetNodes() const; private: const SMDS_Mesh * myMesh; diff --git a/src/SMESHFiltersSelection/SMESH_Type.h b/src/SMESHFiltersSelection/SMESH_Type.h index 7bf427270..a3ba79fa0 100644 --- a/src/SMESHFiltersSelection/SMESH_Type.h +++ b/src/SMESHFiltersSelection/SMESH_Type.h @@ -17,5 +17,6 @@ enum MeshObjectType { SUBMESH_EDGE, SUBMESH_FACE, SUBMESH_SOLID, - SUBMESH_COMPOUND + SUBMESH_COMPOUND, + GROUP }; diff --git a/src/SMESHFiltersSelection/SMESH_TypeFilter.cxx b/src/SMESHFiltersSelection/SMESH_TypeFilter.cxx index 3a14178e5..6514bfd80 100644 --- a/src/SMESHFiltersSelection/SMESH_TypeFilter.cxx +++ b/src/SMESHFiltersSelection/SMESH_TypeFilter.cxx @@ -29,111 +29,92 @@ Standard_Boolean SMESH_TypeFilter::IsOk(const Handle(SALOME_InteractiveObject)& if ( !meshFilter->IsOk(anObj) ) return false; + bool Ok = false; + if ( anObj->hasEntry() ) { QAD_Study* ActiveStudy = QAD_Application::getDesktop()->getActiveStudy(); SALOMEDS::Study_var aStudy = ActiveStudy->getStudyDocument(); SALOMEDS::SObject_var obj = aStudy->FindObjectID( anObj->getEntry() ); - bool Ok = false; + SALOMEDS::SObject_var objFather = obj->GetFather(); + SALOMEDS::SComponent_var objComponent = obj->GetFatherComponent(); + + if ( strlen( obj->GetID() ) <= strlen( objComponent->GetID() ) ) + return false; switch ( myKind ) { case HYPOTHESIS: { - SALOMEDS::SObject_var objFather = obj->GetFather(); - SALOMEDS::SComponent_var objComponent = obj->GetFatherComponent(); if (( objFather->Tag() == 1 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) != 0 ) ) Ok = true; break; } case ALGORITHM: { - SALOMEDS::SObject_var objFather = obj->GetFather(); - SALOMEDS::SComponent_var objComponent = obj->GetFatherComponent(); if (( objFather->Tag() == 2 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) != 0 ) ) Ok = true; break; } case MESH: { - SALOMEDS::SObject_var objFather = obj->GetFather(); - SALOMEDS::SComponent_var objComponent = obj->GetFatherComponent(); - if (( obj->Tag() >= 3 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) == 0 ) ) Ok = true; break; } case SUBMESH: { - SALOMEDS::SObject_var objFather = obj->GetFather(); - SALOMEDS::SComponent_var objComponent = obj->GetFatherComponent(); - - if (( objFather->Tag() >= 4 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) != 0 ) ) + if (( objFather->Tag() >= 4 && objFather->Tag() < 9 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) != 0 ) ) Ok = true; break; } case MESHorSUBMESH: { - SALOMEDS::SObject_var objFather = obj->GetFather(); - SALOMEDS::SComponent_var objComponent = obj->GetFatherComponent(); - if (( obj->Tag() >= 3 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) == 0 ) ) Ok = true; - if (( objFather->Tag() >= 4 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) != 0 ) ) + if (( objFather->Tag() >= 4 && objFather->Tag() < 9 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) != 0 ) ) Ok = true; break; } - case SUBMESH_VERTEX: + case SUBMESH_VERTEX: // Label "SubMeshes on vertexes" { - SALOMEDS::SObject_var objFather = obj->GetFather(); - SALOMEDS::SComponent_var objComponent = obj->GetFatherComponent(); - if (( obj->Tag() == 4 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) != 0 ) && ( objFather->Tag() >= 3 )) Ok = true; break; } case SUBMESH_EDGE: { - SALOMEDS::SObject_var objFather = obj->GetFather(); - SALOMEDS::SComponent_var objComponent = obj->GetFatherComponent(); - if (( obj->Tag() == 5 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) != 0 ) && ( objFather->Tag() >= 3 )) Ok = true; break; } case SUBMESH_FACE: { - SALOMEDS::SObject_var objFather = obj->GetFather(); - SALOMEDS::SComponent_var objComponent = obj->GetFatherComponent(); - if (( obj->Tag() == 6 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) != 0 ) && ( objFather->Tag() >= 3 )) Ok = true; break; } case SUBMESH_SOLID: { - SALOMEDS::SObject_var objFather = obj->GetFather(); - SALOMEDS::SComponent_var objComponent = obj->GetFatherComponent(); - if (( obj->Tag() == 7 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) != 0 ) && ( objFather->Tag() >= 3 )) Ok = true; break; } case SUBMESH_COMPOUND: { - SALOMEDS::SObject_var objFather = obj->GetFather(); - SALOMEDS::SComponent_var objComponent = obj->GetFatherComponent(); - if (( obj->Tag() == 8 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) != 0 ) && ( objFather->Tag() >= 3 )) Ok = true; break; } + case GROUP: + { + if (( objFather->Tag() >= 9 ) && (strcmp( objFather->GetID(), objComponent->GetID() ) != 0 ) ) + Ok = true; + break; + } } - - if ( Ok ) - return true; } - return false; + return Ok; } diff --git a/src/SMESHGUI/Makefile.in b/src/SMESHGUI/Makefile.in index 6f6c98f5b..a183879da 100644 --- a/src/SMESHGUI/Makefile.in +++ b/src/SMESHGUI/Makefile.in @@ -29,14 +29,18 @@ top_srcdir=@top_srcdir@ top_builddir=../.. srcdir=@srcdir@ -VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl:${KERNEL_ROOT_DIR}/idl/salome:${MED_ROOT_DIR}/idl/salome +VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl @COMMENCE@ # header files EXPORT_HEADERS= SMESHGUI_Swig.hxx \ - SMESHGUI_Swig.i + SMESHGUI_Swig.i \ + SMESHGUI.h \ + SMESHGUI_Hypotheses.h \ + SMESHGUI_SpinBox.h \ + SMESHGUI_StudyAPI.h # .po files to transform in .qm PO_FILES = \ @@ -53,28 +57,28 @@ LIB_SRC = SMESHGUI.cxx \ SMESHGUI_AddAlgorithmDlg.cxx \ SMESHGUI_InitMeshDlg.cxx \ SMESHGUI_AddSubMeshDlg.cxx \ - SMESHGUI_LocalLengthDlg.cxx \ - SMESHGUI_NbSegmentsDlg.cxx \ SMESHGUI_TransparencyDlg.cxx \ + SMESHGUI_GroupDlg.cxx \ SMESHGUI_RemoveNodesDlg.cxx \ SMESHGUI_RemoveElementsDlg.cxx \ SMESHGUI_MeshInfosDlg.cxx \ SMESHGUI_Preferences_ColorDlg.cxx \ - SMESHGUI_MaxElementAreaDlg.cxx \ SMESHGUI_Preferences_ScalarBarDlg.cxx \ - SMESHGUI_EditScalarBarDlg.cxx \ + SMESHGUI_Preferences_SelectionDlg.cxx \ SMESHGUI_aParameterDlg.cxx \ - SMESHGUI_MaxElementVolumeDlg.cxx \ SMESHGUI_Swig.cxx \ SMESHGUI_ComputeScalarValue.cxx \ SMESHGUI_MoveNodesDlg.cxx \ SMESHGUI_OrientationElementsDlg.cxx \ SMESHGUI_DiagonalInversionDlg.cxx \ - SMESHGUI_EdgesConnectivityDlg.cxx \ SMESHGUI_AddFaceDlg.cxx \ SMESHGUI_AddVolumeDlg.cxx \ SMESHGUI_AddEdgeDlg.cxx \ - SMESHGUI_EditHypothesesDlg.cxx + SMESHGUI_EditHypothesesDlg.cxx \ + SMESHGUI_CreateHypothesesDlg.cxx \ + SMESHGUI_XmlHandler.cxx \ + SMESHGUI_Filter.cxx \ + SMESHGUI_FilterDlg.cxx LIB_MOC = \ SMESHGUI.h \ @@ -84,26 +88,24 @@ LIB_MOC = \ SMESHGUI_AddAlgorithmDlg.h \ SMESHGUI_InitMeshDlg.h \ SMESHGUI_AddSubMeshDlg.h \ - SMESHGUI_LocalLengthDlg.h \ - SMESHGUI_NbSegmentsDlg.h \ SMESHGUI_TransparencyDlg.h \ + SMESHGUI_GroupDlg.h \ SMESHGUI_RemoveNodesDlg.h \ SMESHGUI_RemoveElementsDlg.h \ SMESHGUI_MeshInfosDlg.h \ SMESHGUI_Preferences_ColorDlg.h \ - SMESHGUI_MaxElementAreaDlg.h \ SMESHGUI_Preferences_ScalarBarDlg.h \ - SMESHGUI_EditScalarBarDlg.h \ + SMESHGUI_Preferences_SelectionDlg.h \ SMESHGUI_aParameterDlg.h \ - SMESHGUI_MaxElementVolumeDlg.h \ SMESHGUI_MoveNodesDlg.h \ SMESHGUI_OrientationElementsDlg.h \ SMESHGUI_DiagonalInversionDlg.h \ - SMESHGUI_EdgesConnectivityDlg.h \ SMESHGUI_AddEdgeDlg.h \ SMESHGUI_AddVolumeDlg.h \ SMESHGUI_AddFaceDlg.h \ - SMESHGUI_EditHypothesesDlg.h + SMESHGUI_EditHypothesesDlg.h \ + SMESHGUI_CreateHypothesesDlg.h \ + SMESHGUI_FilterDlg.h LIB_CLIENT_IDL = SALOME_Exception.idl \ GEOM_Gen.idl \ @@ -111,21 +113,25 @@ LIB_CLIENT_IDL = SALOME_Exception.idl \ SMESH_Gen.idl \ SMESH_Mesh.idl \ SMESH_Hypothesis.idl \ - SMESH_BasicHypothesis.idl \ + SMESH_Group.idl \ SALOMEDS.idl \ SALOMEDS_Attributes.idl \ SALOME_ModuleCatalog.idl \ SALOME_Component.idl \ - MED.idl + MED.idl \ + SMESH_Filter.idl \ + SALOME_GenericObj.idl LIB_SERVER_IDL = # additionnal information to compil and link file -CPPFLAGS += $(QT_INCLUDES) $(VTK_INCLUDES) $(OGL_INCLUDES) $(OCC_INCLUDES) $(PYTHON_INCLUDES) $(MED2_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome +CPPFLAGS += $(QT_INCLUDES) $(VTK_INCLUDES) $(OGL_INCLUDES) $(OCC_INCLUDES) $(PYTHON_INCLUDES) \ + $(MED2_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome \ + $(BOOST_CPPFLAGS) CXXFLAGS += -I${KERNEL_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome #$(OCC_CXXFLAGS) -LDFLAGS += -lOCCViewer -lVTKViewer -lSalomeObject -lSalomeGUI -lSMESHObject -lSMDS -lSMESHDS -lSMESHFiltersSelection -lGEOMClient $(OCC_KERNEL_LIBS) -L${KERNEL_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome +LDFLAGS += -lOCCViewer -lVTKViewer -lSalomeObject -lSalomeGUI -lSMESHObject -lSMDS -lSMESHDS -lSMESHFiltersSelection -lGEOMClient -lMeshDriverDAT -lMeshDriverMED -lMeshDriverUNV $(OCC_KERNEL_LIBS) -L${KERNEL_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome -lSalomeGenericObj @CONCLUDE@ diff --git a/src/SMESHGUI/SMESHBin.cxx b/src/SMESHGUI/SMESHBin.cxx new file mode 100644 index 000000000..61f9777fe --- /dev/null +++ b/src/SMESHGUI/SMESHBin.cxx @@ -0,0 +1,4 @@ +int main(int argc, char** argv){ + return 0; +} + diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index d66bd07f6..4d94be4c8 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -17,45 +17,42 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org -// -// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org // // File : SMESHGUI.cxx // Author : Nicolas REJNERI // Module : SMESH // $Header$ -using namespace std; #include "SMESHGUI.h" #include "SMESHGUI_AddHypothesisDlg.h" #include "SMESHGUI_AddAlgorithmDlg.h" #include "SMESHGUI_InitMeshDlg.h" -#include "SMESHGUI_LocalLengthDlg.h" -#include "SMESHGUI_NbSegmentsDlg.h" #include "SMESHGUI_AddSubMeshDlg.h" #include "SMESHGUI_NodesDlg.h" #include "SMESHGUI_TransparencyDlg.h" +#include "SMESHGUI_GroupDlg.h" #include "SMESHGUI_RemoveNodesDlg.h" #include "SMESHGUI_RemoveElementsDlg.h" #include "SMESHGUI_MeshInfosDlg.h" #include "SMESHGUI_Preferences_ColorDlg.h" -#include "SMESHGUI_MaxElementAreaDlg.h" -#include "SMESHGUI_MaxElementVolumeDlg.h" #include "SMESHGUI_Preferences_ScalarBarDlg.h" -#include "SMESHGUI_EditScalarBarDlg.h" +#include "SMESHGUI_Preferences_SelectionDlg.h" #include "SMESHGUI_aParameterDlg.h" #include "SMESHGUI_ComputeScalarValue.h" #include "SMESHGUI_MoveNodesDlg.h" #include "SMESHGUI_OrientationElementsDlg.h" #include "SMESHGUI_DiagonalInversionDlg.h" -#include "SMESHGUI_EdgesConnectivityDlg.h" #include "SMESHGUI_AddFaceDlg.h" #include "SMESHGUI_AddEdgeDlg.h" #include "SMESHGUI_AddVolumeDlg.h" #include "SMESHGUI_EditHypothesesDlg.h" +#include "SMESHGUI_CreateHypothesesDlg.h" +#include "SMESHGUI_FilterDlg.h" +#include "SMESHGUI_XmlHandler.h" -#include "SMESH_Grid.h" +#include "SMESH_Actor.h" +#include "SMESH_Object.h" // SALOME Includes #include "Utils_ORB_INIT.hxx" @@ -69,23 +66,47 @@ using namespace std; #include "QAD_MessageBox.h" #include "QAD_Resource.h" #include "QAD_FileDlg.h" -#include "SALOMEGUI_Desktop.h" -#include "SALOMEGUI_NameDlg.h" +#include "QAD_Desktop.h" +#include "QAD_ResourceMgr.h" +#include "QAD_WaitCursor.h" #include "OCCViewer_ViewPort.h" #include "OCCViewer_ViewPort3d.h" #include "OCCViewer_Viewer3d.h" -#include "GEOM_Client.hxx" #include "GEOM_InteractiveObject.hxx" #include "SALOME_NamingService.hxx" #include "SALOME_ListIteratorOfListIO.hxx" #include "SALOME_InteractiveObject.hxx" +#include "SALOMEGUI_Desktop.h" +#include "SALOMEGUI_NameDlg.h" #include "SALOMEGUI_ImportOperation.h" #include "SALOMEGUI_QtCatchCorbaException.hxx" + #include "utilities.h" +#include + +#include "SMDS_Mesh.hxx" +#include "SMESHDS_Document.hxx" +#include "Document_Reader.h" +#include "Document_Writer.h" +#include "Mesh_Reader.h" +#include "Mesh_Writer.h" + +#include "DriverDAT_R_SMESHDS_Document.h" +#include "DriverMED_R_SMESHDS_Document.h" +#include "DriverUNV_R_SMESHDS_Document.h" +#include "DriverDAT_W_SMESHDS_Document.h" +#include "DriverMED_W_SMESHDS_Document.h" +#include "DriverUNV_W_SMESHDS_Document.h" +#include "DriverDAT_R_SMESHDS_Mesh.h" +#include "DriverMED_R_SMESHDS_Mesh.h" +#include "DriverUNV_R_SMESHDS_Mesh.h" +#include "DriverDAT_W_SMESHDS_Mesh.h" +#include "DriverMED_W_SMESHDS_Mesh.h" +#include "DriverUNV_W_SMESHDS_Mesh.h" // QT Includes #define INCLUDE_MENUITEM_DEF @@ -98,7 +119,6 @@ using namespace std; #include #include #include -#include #include #include #include @@ -108,18 +128,367 @@ using namespace std; // VTK Includes #include "VTKViewer_Common.h" #include "VTKViewer_ViewFrame.h" +#include "VTKViewer_InteractorStyleSALOME.h" + +#include #include #include #include +#include // Open CASCADE Includes #include #include -static GEOM_Client ShapeReader; +#include + static SMESHGUI *smeshGUI = 0; static CORBA::ORB_var _orb; +using namespace std; + +typedef pair TKeyOfVisualObj; +typedef boost::shared_ptr TVisualObjPtr; +typedef map TVisualObjCont; +static TVisualObjCont VISUALOBJCONT; + + +TVisualObjPtr GetVisualObj(int theStudyId, const char* theEntry){ + TVisualObjPtr aVisualObj; + try{ + TVisualObjCont::key_type aKey(theStudyId,theEntry); + TVisualObjCont::iterator anIter = VISUALOBJCONT.find(aKey); + if(anIter != VISUALOBJCONT.end()){ + aVisualObj = anIter->second; + }else{ + SALOMEDS::Study_var aStudy = QAD_Application::getDesktop()->getActiveStudy()->getStudyDocument(); + SALOMEDS::SObject_var aSObj = aStudy->FindObjectID(theEntry); + if(!CORBA::is_nil(aSObj)){ + SALOMEDS::GenericAttribute_var anAttr; + if(aSObj->FindAttribute(anAttr,"AttributeIOR")){ + SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + CORBA::String_var aVal = anIOR->Value(); + CORBA::Object_var anObj =_orb->string_to_object(aVal.in()); + if(!CORBA::is_nil(anObj)){ + //Try narrow to SMESH_Mesh interafce + SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(anObj); + if(!aMesh->_is_nil()){ + aVisualObj.reset(new SMESH_MeshObj(aMesh)); + aVisualObj->Update(); + TVisualObjCont::value_type aValue(aKey,aVisualObj); + VISUALOBJCONT.insert(aValue); + return aVisualObj; + } + //Try narrow to SMESH_Group interafce + SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow(anObj); + if(!aGroup->_is_nil()){ + SALOMEDS::SObject_var aFatherSObj = aSObj->GetFather(); + if(aFatherSObj->_is_nil()) return aVisualObj; + aFatherSObj = aFatherSObj->GetFather(); + if(aFatherSObj->_is_nil()) return aVisualObj; + CORBA::String_var anEntry = aFatherSObj->GetID(); + TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in()); + if(SMESH_MeshObj* aMeshObj = dynamic_cast(aVisObj.get())){ + aVisualObj.reset(new SMESH_GroupObj(aGroup,aMeshObj)); + aVisualObj->Update(); + TVisualObjCont::value_type aValue(aKey,aVisualObj); + VISUALOBJCONT.insert(aValue); + return aVisualObj; + } + } + //Try narrow to SMESH_subMesh interafce + SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(anObj); + if(!aSubMesh->_is_nil()){ + SALOMEDS::SObject_var aFatherSObj = aSObj->GetFather(); + if(aFatherSObj->_is_nil()) return aVisualObj; + aFatherSObj = aFatherSObj->GetFather(); + if(aFatherSObj->_is_nil()) return aVisualObj; + CORBA::String_var anEntry = aFatherSObj->GetID(); + TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in()); + if(SMESH_MeshObj* aMeshObj = dynamic_cast(aVisObj.get())){ + aVisualObj.reset(new SMESH_subMeshObj(aSubMesh,aMeshObj)); + aVisualObj->Update(); + TVisualObjCont::value_type aValue(aKey,aVisualObj); + VISUALOBJCONT.insert(aValue); + return aVisualObj; + } + } + } + } + } + } + }catch(...){ + INFOS("GetMeshObj - There is no SMESH_Mesh object for the SALOMEDS::Strudy and Entry!!!"); + } + return aVisualObj; +} + + +VTKViewer_ViewFrame* GetVtkViewFrame(QAD_StudyFrame* theStudyFrame){ + QAD_ViewFrame* aViewFrame = theStudyFrame->getRightFrame()->getViewFrame(); + return dynamic_cast(aViewFrame); +} + +void UpdateSelectionProp() { + QAD_Study* aStudy = SMESHGUI::GetSMESHGUI()->GetActiveStudy(); + QList aFrameList = aStudy->getStudyFrames(); + + QString SCr, SCg, SCb; + SCr = QAD_CONFIG->getSetting("SMESH:SettingsSelectColorRed"); + SCg = QAD_CONFIG->getSetting("SMESH:SettingsSelectColorGreen"); + SCb = QAD_CONFIG->getSetting("SMESH:SettingsSelectColorBlue"); + QColor aHiColor = Qt::white; + if (!SCr.isEmpty() && !SCg.isEmpty() && !SCb.isEmpty()) + aHiColor = QColor(SCr.toInt(), SCg.toInt(), SCb.toInt()); + + SCr = QAD_CONFIG->getSetting("SMESH:SettingsItemSelectColorRed"); + SCg = QAD_CONFIG->getSetting("SMESH:SettingsItemSelectColorGreen"); + SCb = QAD_CONFIG->getSetting("SMESH:SettingsItemSelectColorBlue"); + QColor aSelColor = Qt::yellow; + if (!SCr.isEmpty() && !SCg.isEmpty() && !SCb.isEmpty()) + aSelColor = QColor(SCr.toInt(), SCg.toInt(), SCb.toInt()); + QString SW = QAD_CONFIG->getSetting("SMESH:SettingsItemSelectWidth"); + if (SW.isEmpty()) SW = "5"; + + SCr = QAD_CONFIG->getSetting("SMESH:SettingsPreSelectColorRed"); + SCg = QAD_CONFIG->getSetting("SMESH:SettingsPreSelectColorGreen"); + SCb = QAD_CONFIG->getSetting("SMESH:SettingsPreSelectColorBlue"); + QColor aPreColor = Qt::cyan; + if (!SCr.isEmpty() && !SCg.isEmpty() && !SCb.isEmpty()) + aPreColor = QColor(SCr.toInt(), SCg.toInt(), SCb.toInt()); + QString PW = QAD_CONFIG->getSetting("SMESH:SettingsPreSelectWidth"); + if (PW.isEmpty()) PW = "5"; + + QString SP1 = QAD_CONFIG->getSetting("SMESH:SettingsNodeSelectTol"); + if (SP1.isEmpty()) SP1 = "0.025"; + QString SP2 = QAD_CONFIG->getSetting("SMESH:SettingsElementsSelectTol"); + if (SP2.isEmpty()) SP2 = "0.001"; + + for (QAD_StudyFrame* aStudyFrame = aFrameList.first(); aStudyFrame; aStudyFrame = aFrameList.next()) { + if (aStudyFrame->getTypeView() == VIEW_VTK) { + VTKViewer_ViewFrame* aVtkViewFrame = GetVtkViewFrame(aStudyFrame); + if (!aVtkViewFrame) continue; + // update VTK viewer properties + VTKViewer_RenderWindowInteractor* anInteractor = aVtkViewFrame->getRWInteractor(); + if (anInteractor) { + // mesh element selection + anInteractor->SetSelectionProp(aSelColor.red()/255., aSelColor.green()/255., + aSelColor.blue()/255., SW.toInt()); + + // tolerances + anInteractor->SetSelectionTolerance(SP1.toDouble(), SP2.toDouble()); + + // pre-selection + VTKViewer_InteractorStyleSALOME* aStyle = anInteractor->GetInteractorStyleSALOME(); + if (aStyle) { + aStyle->setPreselectionProp(aPreColor.red()/255., aPreColor.green()/255., + aPreColor.blue()/255., PW.toInt()); + } + } + // update actors + vtkRenderer* aRenderer = aVtkViewFrame->getRenderer(); + vtkActorCollection *aCollection = aRenderer->GetActors(); + aCollection->InitTraversal(); + while(vtkActor *anAct = aCollection->GetNextActor()){ + if(SMESH_Actor *anActor = dynamic_cast(anAct)){ + anActor->SetHighlightColor(aHiColor.red()/255., aHiColor.green()/255., + aHiColor.blue()/255.); + anActor->SetPreHighlightColor(aPreColor.red()/255., aPreColor.green()/255., + aPreColor.blue()/255.); + } + } + } + } +} + +VTKViewer_ViewFrame* GetCurrentVtkView(){ + QAD_Study* aStudy = SMESHGUI::GetSMESHGUI()->GetActiveStudy(); + QAD_StudyFrame *aStudyFrame = aStudy->getActiveStudyFrame(); + return GetVtkViewFrame(aStudyFrame); +} + + +SMESH_Actor* FindActorByEntry(QAD_StudyFrame *theStudyFrame, + const char* theEntry) +{ + if(VTKViewer_ViewFrame* aViewFrame = GetVtkViewFrame(theStudyFrame)){ + vtkRenderer *aRenderer = aViewFrame->getRenderer(); + vtkActorCollection *aCollection = aRenderer->GetActors(); + aCollection->InitTraversal(); + while(vtkActor *anAct = aCollection->GetNextActor()){ + if(SMESH_Actor *anActor = dynamic_cast(anAct)){ + if(anActor->hasIO()){ + Handle(SALOME_InteractiveObject) anIO = anActor->getIO(); + if(anIO->hasEntry() && strcmp(anIO->getEntry(),theEntry) == 0){ + return anActor; + } + } + } + } + } + return NULL; +} + + +SMESH_Actor* FindActorByEntry(const char* theEntry){ + QAD_Study* aStudy = SMESHGUI::GetSMESHGUI()->GetActiveStudy(); + QAD_StudyFrame *aStudyFrame = aStudy->getActiveStudyFrame(); + return FindActorByEntry(aStudyFrame,theEntry); +} + + +SMESH_Actor* CreateActor(SALOMEDS::Study_ptr theStudy, + const char* theEntry, + int theIsClear = false) +{ + SMESH_Actor *anActor = NULL; + CORBA::Long anId = theStudy->StudyId(); + if(TVisualObjPtr aVisualObj = GetVisualObj(anId,theEntry)){ + SALOMEDS::SObject_var aSObj = theStudy->FindObjectID(theEntry); + if(!aSObj->_is_nil()){ + SALOMEDS::GenericAttribute_var anAttr; + if(aSObj->FindAttribute(anAttr,"AttributeName")){ + SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr); + CORBA::String_var aVal = aName->Value(); + string aNameVal = aVal.in(); + SMESH::FilterManager_ptr aFilterMgr = smeshGUI->GetFilterMgr(); + anActor = SMESH_Actor::New(aVisualObj,aFilterMgr,theEntry,aNameVal.c_str(),theIsClear); + } + } + } + return anActor; +} + + +void DisplayActor(QAD_StudyFrame *theStudyFrame, SMESH_Actor* theActor){ + if(VTKViewer_ViewFrame* aViewFrame = GetVtkViewFrame(theStudyFrame)){ + aViewFrame->AddActor(theActor); + aViewFrame->Repaint(); + } +} + + +void RemoveActor(QAD_StudyFrame *theStudyFrame, SMESH_Actor* theActor){ + if(VTKViewer_ViewFrame* aViewFrame = GetVtkViewFrame(theStudyFrame)){ + aViewFrame->RemoveActor(theActor); + aViewFrame->Repaint(); + } +} + + +void FitAll(){ + if(VTKViewer_ViewFrame* aViewFrame = GetCurrentVtkView()){ + aViewFrame->onViewFitAll(); + aViewFrame->Repaint(); + } +} + +vtkRenderer* GetCurrentRenderer(){ + if(VTKViewer_ViewFrame* aViewFrame = GetCurrentVtkView()) + return aViewFrame->getRenderer(); + return NULL; +} + +void RepaintCurrentView(){ + if(VTKViewer_ViewFrame* aViewFrame = GetCurrentVtkView()) + aViewFrame->Repaint(); +} + + +enum EDisplaing {eDisplayAll, eDisplay, eDisplayOnly, eErase, eEraseAll}; +void UpdateView(QAD_StudyFrame *theStudyFrame, EDisplaing theAction, + const char* theEntry = "") +{ + if(VTKViewer_ViewFrame* aViewFrame = GetVtkViewFrame(theStudyFrame)){ + vtkRenderer *aRenderer = aViewFrame->getRenderer(); + vtkActorCollection *aCollection = aRenderer->GetActors(); + aCollection->InitTraversal(); + switch(theAction){ + case eDisplayAll: { + while(vtkActor *anAct = aCollection->GetNextActor()){ + if(SMESH_Actor *anActor = dynamic_cast(anAct)){ + anActor->SetVisibility(true); + } + } + break; + } + case eDisplayOnly: + case eEraseAll: { + while(vtkActor *anAct = aCollection->GetNextActor()){ + if(SMESH_Actor *anActor = dynamic_cast(anAct)){ + anActor->SetVisibility(false); + } + } + } + default: { + if(SMESH_Actor *anActor = FindActorByEntry(theStudyFrame,theEntry)){ + switch(theAction) { + case eDisplay: + case eDisplayOnly: + anActor->SetVisibility(true); + break; + case eErase: + anActor->SetVisibility(false); + break; + } + } else { + switch(theAction){ + case eDisplay: + case eDisplayOnly:{ + QAD_Study* aStudy = theStudyFrame->getStudy(); + SALOMEDS::Study_var aDocument = aStudy->getStudyDocument(); + if(anActor = CreateActor(aDocument,theEntry,true)) { + DisplayActor(theStudyFrame,anActor); + FitAll(); + } + break; + } + } + } + } + } + } +} + + +void UpdateView(EDisplaing theAction, const char* theEntry = ""){ + QAD_Study* aStudy = SMESHGUI::GetSMESHGUI()->GetActiveStudy(); + QAD_StudyFrame *aStudyFrame = aStudy->getActiveStudyFrame(); + UpdateView(aStudyFrame,theAction,theEntry); +} + +static bool IsReferencedObject( SALOMEDS::SObject_ptr SO ) +{ + if ( !SO->_is_nil() ) { + SALOMEDS::GenericAttribute_var anAttr; + if ( SO->FindAttribute( anAttr, "AttributeTarget" ) ) { + SALOMEDS::AttributeTarget_var aTarget = SALOMEDS::AttributeTarget::_narrow( anAttr ); + SALOMEDS::Study::ListOfSObject_var aList = aTarget->Get(); + if ( aList->length() > 0 ) { + return true; + } + } + } + return false; +} + +void SetPointRepresentation(bool theIsVisible){ + if(VTKViewer_ViewFrame* aViewFrame = GetCurrentVtkView()){ + vtkRenderer *aRenderer = aViewFrame->getRenderer(); + vtkActorCollection *aCollection = aRenderer->GetActors(); + aCollection->InitTraversal(); + while(vtkActor *anAct = aCollection->GetNextActor()){ + if(SMESH_Actor *anActor = dynamic_cast(anAct)){ + if(anActor->GetVisibility()){ + anActor->SetPointRepresentation(theIsVisible); + } + } + } + RepaintCurrentView(); + } +} + + //============================================================================= /*! * @@ -127,30 +496,30 @@ static CORBA::ORB_var _orb; //============================================================================= class CustomItem:public QCustomMenuItem { - public: - CustomItem(const QString & s, const QFont & f):string(s), font(f) - { - }; - ~CustomItem() - { - } - - void paint(QPainter * p, const QColorGroup & /*cg */ , bool /*act */ , - bool /*enabled */ , int x, int y, int w, int h) - { - p->setFont(font); - p->drawText(x, y, w, h, - AlignHCenter | AlignVCenter | ShowPrefix | DontClip, string); - } - - QSize sizeHint() - { - return QFontMetrics(font). - size(AlignHCenter | AlignVCenter | ShowPrefix | DontClip, string); - } - private: - QString string; - QFont font; + public: + CustomItem(const QString & s, const QFont & f):string(s), font(f) + { + }; + ~CustomItem() + { + } + + void paint(QPainter * p, const QColorGroup & /*cg */ , bool /*act */ , + bool /*enabled */ , int x, int y, int w, int h) + { + p->setFont(font); + p->drawText(x, y, w, h, + AlignHCenter | AlignVCenter | ShowPrefix | DontClip, string); + } + + QSize sizeHint() + { + return QFontMetrics(font). + size(AlignHCenter | AlignVCenter | ShowPrefix | DontClip, string); + } + private: + QString string; + QFont font; }; //============================================================================= @@ -158,8 +527,8 @@ class CustomItem:public QCustomMenuItem * */ //============================================================================= -SMESHGUI::SMESHGUI(): -QObject() +SMESHGUI::SMESHGUI( const QString& theName, QObject* theParent ) : + SALOMEGUI( theName, theParent ) { } @@ -177,63 +546,78 @@ SMESHGUI::~SMESHGUI() * */ //============================================================================= -SMESHGUI *SMESHGUI::GetSMESHGUI() +SMESHGUI* SMESHGUI::GetSMESHGUI() { - return smeshGUI; + if ( !smeshGUI ) + GetOrCreateSMESHGUI( QAD_Application::getDesktop() ); + return smeshGUI; } +extern "C" +{ + Standard_EXPORT SALOMEGUI* GetComponentGUI() { + return SMESHGUI::GetSMESHGUI(); + } +} //============================================================================= /*! * */ //============================================================================= -SMESHGUI *SMESHGUI::GetOrCreateSMESHGUI(QAD_Desktop * desktop) +SMESHGUI* SMESHGUI::GetOrCreateSMESHGUI( QAD_Desktop* desktop ) { - if (smeshGUI == 0) - { - setOrb(); - smeshGUI = new SMESHGUI; - smeshGUI->myActiveDialogBox = 0; - smeshGUI->myState = -1; - smeshGUI->myDesktop = desktop; - smeshGUI->myActiveStudy = desktop->getActiveStudy(); - - Engines::Component_var comp = - desktop->getEngine("FactoryServer", "SMESH"); - smeshGUI->myComponentMesh = SMESH::SMESH_Gen::_narrow(comp); - - Engines::Component_var comp1 = - desktop->getEngine("FactoryServer", "GEOM"); - smeshGUI->myComponentGeom = GEOM::GEOM_Gen::_narrow(comp1); - - /* GetCurrentStudy */ - smeshGUI->myStudyId = smeshGUI->myActiveStudy->getStudyId(); - - smeshGUI->myComponentGeom->GetCurrentStudy(smeshGUI->myStudyId); - // smeshGUI->myComponentGeom->NbLabels(); - - smeshGUI->myStudy = smeshGUI->myActiveStudy->getStudyDocument(); - - smeshGUI->myStudyAPI = - SMESHGUI_StudyAPI(smeshGUI->myStudy, smeshGUI->myComponentMesh); - - smeshGUI->mySimulationActors = vtkActorCollection::New(); - smeshGUI->mySimulationActors2D = vtkActor2DCollection::New(); - } - else - { - /* study may have changed */ - smeshGUI->myActiveStudy = desktop->getActiveStudy(); - smeshGUI->myStudyAPI.Update(smeshGUI->myComponentMesh); - } - - /* Automatic Update */ - if (desktop->menuBar()->isItemChecked(1001)) - smeshGUI->myAutomaticUpdate = true; - else - smeshGUI->myAutomaticUpdate = false; - - return smeshGUI; + if( !smeshGUI ) { + setOrb(); + smeshGUI = new SMESHGUI; + smeshGUI->myActiveDialogBox = 0 ; + smeshGUI->myState = -1 ; + smeshGUI->myDesktop = desktop ; + + /* get smesh engine */ + Engines::Component_var comp = desktop->getEngine("FactoryServer", "SMESH"); + smeshGUI->myComponentMesh = SMESH::SMESH_Gen::_narrow(comp); + + /* get geom engine */ + Engines::Component_var comp1 = desktop->getEngine("FactoryServer", "GEOM"); + smeshGUI->myComponentGeom = GEOM::GEOM_Gen::_narrow(comp1); + + /* set current study */ + smeshGUI->myActiveStudy = desktop->getActiveStudy(); + smeshGUI->myStudyId = smeshGUI->myActiveStudy->getStudyId(); + smeshGUI->myStudy = smeshGUI->myActiveStudy->getStudyDocument(); + smeshGUI->myComponentGeom->GetCurrentStudy( smeshGUI->myStudyId ); + smeshGUI->myComponentMesh->SetCurrentStudy( smeshGUI->myStudy ); + // smeshGUI->myComponentGeom->NbLabels(); + + /* create service object */ + smeshGUI->myStudyAPI = SMESHGUI_StudyAPI(smeshGUI->myStudy, smeshGUI->myComponentMesh); + + smeshGUI->myDocument = new SMESHDS_Document(1);//NBU + + smeshGUI->mySimulationActors = vtkActorCollection::New(); + smeshGUI->mySimulationActors2D = vtkActor2DCollection::New(); + + /*filter manager*/ + smeshGUI->myFilterMgr = smeshGUI->myComponentMesh->CreateFilterManager(); + + /* load resources for all available meshers */ + smeshGUI->InitAvailableHypotheses(); + } else { + /* study may have changed - set current study */ + smeshGUI->myActiveStudy = desktop->getActiveStudy(); + smeshGUI->myStudyId = smeshGUI->myActiveStudy->getStudyId(); + smeshGUI->myStudy = smeshGUI->myActiveStudy->getStudyDocument(); + smeshGUI->myComponentGeom->GetCurrentStudy( smeshGUI->myStudyId ); + smeshGUI->myComponentMesh->SetCurrentStudy( smeshGUI->myStudy ); + + // Set active study to Study API + smeshGUI->myStudyAPI.Update( smeshGUI->myStudy ); + } + + /* Automatic Update flag */ + smeshGUI->myAutomaticUpdate = ( QAD_CONFIG->getSetting( "SMESH:AutomaticUpdate" ).compare( "true" ) == 0 ); + + return smeshGUI; } //============================================================================= @@ -243,8 +627,8 @@ SMESHGUI *SMESHGUI::GetOrCreateSMESHGUI(QAD_Desktop * desktop) //============================================================================= void SMESHGUI::SetState(int aState) { - this->myState = aState; - return; + this->myState = aState; + return; } //============================================================================= @@ -254,8 +638,8 @@ void SMESHGUI::SetState(int aState) //============================================================================= void SMESHGUI::ResetState() { - this->myState = -1; - return; + this->myState = -1; + return; } //============================================================================= @@ -265,8 +649,8 @@ void SMESHGUI::ResetState() //============================================================================= void SMESHGUI::EmitSignalDeactivateDialog() { - emit this->SignalDeactivateActiveDialog(); - return; + emit this->SignalDeactivateActiveDialog(); + return; } //============================================================================= @@ -276,8 +660,8 @@ void SMESHGUI::EmitSignalDeactivateDialog() //============================================================================= void SMESHGUI::EmitSignalCloseAllDialogs() { - emit this->SignalCloseAllDialogs(); - return; + emit SignalCloseAllDialogs(); + return; } //============================================================================= @@ -287,7 +671,7 @@ void SMESHGUI::EmitSignalCloseAllDialogs() //============================================================================= QDialog *SMESHGUI::GetActiveDialogBox() { - return this->myActiveDialogBox; + return this->myActiveDialogBox; } //============================================================================= @@ -297,8 +681,8 @@ QDialog *SMESHGUI::GetActiveDialogBox() //============================================================================= void SMESHGUI::SetActiveDialogBox(QDialog * aDlg) { - this->myActiveDialogBox = (QDialog *) aDlg; - return; + this->myActiveDialogBox = (QDialog *) aDlg; + return; } //============================================================================= @@ -308,7 +692,7 @@ void SMESHGUI::SetActiveDialogBox(QDialog * aDlg) //============================================================================= QAD_Study *SMESHGUI::GetActiveStudy() { - return this->myActiveStudy; + return this->myActiveStudy; } //============================================================================= @@ -318,7 +702,7 @@ QAD_Study *SMESHGUI::GetActiveStudy() //============================================================================= SALOMEDS::Study_ptr SMESHGUI::GetStudy() { - return SALOMEDS::Study::_narrow(myStudy); + return SALOMEDS::Study::_narrow(myStudy); } //============================================================================= @@ -328,7 +712,7 @@ SALOMEDS::Study_ptr SMESHGUI::GetStudy() //============================================================================= SMESHGUI_StudyAPI SMESHGUI::GetStudyAPI() { - return myStudyAPI; + return myStudyAPI; } //============================================================================= @@ -338,7 +722,7 @@ SMESHGUI_StudyAPI SMESHGUI::GetStudyAPI() //============================================================================= QAD_Desktop *SMESHGUI::GetDesktop() { - return this->myDesktop; + return this->myDesktop; } //============================================================================= @@ -346,21 +730,24 @@ QAD_Desktop *SMESHGUI::GetDesktop() * */ //============================================================================= -vtkScalarBarActor *SMESHGUI::GetScalarBar() +bool SMESHGUI::ActiveStudyChanged(QAD_Desktop* parent) { - vtkRenderer *aRenderer = - ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()-> - getRightFrame()->getViewFrame())->getRenderer(); - vtkActor2DCollection *actor2DList = aRenderer->GetActors2D(); - actor2DList->InitTraversal(); - vtkActor2D *aActor2d = actor2DList->GetNextActor2D(); - while (aActor2d != NULL) - { - if (aActor2d->IsA("vtkScalarBarActor")) - return vtkScalarBarActor::SafeDownCast(aActor2d); - actor2DList->GetNextActor2D(); - } - return NULL; + MESSAGE("SMESHGUI::activeStudyChanged init."); + QAD_Study* prevStudy = 0; + if ( smeshGUI ) + prevStudy = smeshGUI->myActiveStudy; + /* Create or retrieve an object SMESHGUI */ + MESSAGE("Active study changed : prev study =" << prevStudy); + SMESHGUI::GetOrCreateSMESHGUI( parent ); + MESSAGE("Active study changed : active study =" << smeshGUI->myActiveStudy); + if ( prevStudy != smeshGUI->myActiveStudy ) { + smeshGUI->EmitSignalCloseAllDialogs(); + MESSAGE("Active study changed : SMESHGUI nullified" << endl); + //smeshGUI = 0; + ::UpdateSelectionProp(); + } + MESSAGE("SMESHGUI::activeStudyChanged done."); + return true; } //============================================================================= @@ -368,20 +755,15 @@ vtkScalarBarActor *SMESHGUI::GetScalarBar() * */ //============================================================================= -void SMESHGUI::activeStudyChanged(QAD_Desktop * parent) +bool SMESHGUI::DefineDlgPosition(QWidget * aDlg, int &x, int &y) { - MESSAGE("SMESHGUI::activeStudyChanged init.") - /* Create or retrieve an object SMESHGUI */ - SMESHGUI::GetOrCreateSMESHGUI(parent); - if (smeshGUI != 0) - { - smeshGUI->EmitSignalCloseAllDialogs(); - MESSAGE("Active study changed : SMESHGUI nullified" << endl); - smeshGUI = 0; - } - - //smeshGUI->SetSettings( parent ); //DCQ : Pb. Multi-Etudes - MESSAGE("SMESHGUI::activeStudyChanged done.") return; + /* Here the position is on the bottom right corner - 10 */ + // aDlg->resize(QSize().expandedTo(aDlg->minimumSizeHint())); + aDlg->adjustSize(); + QAD_Desktop *PP = QAD_Application::getDesktop(); + x = abs(PP->x() + PP->size().width() - aDlg->size().width() - 10); + y = abs(PP->y() + PP->size().height() - aDlg->size().height() - 10); + return true; } //============================================================================= @@ -389,14 +771,39 @@ void SMESHGUI::activeStudyChanged(QAD_Desktop * parent) * */ //============================================================================= -bool SMESHGUI::DefineDlgPosition(QWidget * aDlg, int &x, int &y) +void SMESHGUI::EraseSimulationActors() { - /* Here the position is on the bottom right corner - 10 */ - aDlg->resize(QSize().expandedTo(aDlg->minimumSizeHint())); - QAD_Desktop *PP = QAD_Application::getDesktop(); - x = abs(PP->x() + PP->size().width() - aDlg->size().width() - 10); - y = abs(PP->y() + PP->size().height() - aDlg->size().height() - 10); - return true; + if (myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) + { //VTK + vtkRenderer *theRenderer = + ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()-> + getRightFrame()->getViewFrame())->getRenderer(); + vtkRenderWindow *renWin = theRenderer->GetRenderWindow(); + + if (mySimulationActors != NULL) + { + mySimulationActors->InitTraversal(); + vtkActor *ac = mySimulationActors->GetNextActor(); + while (!(ac == NULL)) + { + theRenderer->RemoveActor(ac); + ac = mySimulationActors->GetNextActor(); + } + mySimulationActors->RemoveAllItems(); + } + if (mySimulationActors2D != NULL) + { + mySimulationActors2D->InitTraversal(); + vtkActor2D *ac = mySimulationActors2D->GetNextActor2D(); + while (!(ac == NULL)) + { + theRenderer->RemoveActor2D(ac); + ac = mySimulationActors2D->GetNextActor2D(); + } + mySimulationActors2D->RemoveAllItems(); + } + SetPointRepresentation(false); + } } //============================================================================= @@ -404,40 +811,23 @@ bool SMESHGUI::DefineDlgPosition(QWidget * aDlg, int &x, int &y) * */ //============================================================================= -void SMESHGUI::EraseSimulationActors() +SMESH::SMESH_Mesh_ptr SMESHGUI::InitMesh( GEOM::GEOM_Shape_ptr aShape, + QString NameMesh ) { - if (myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) - { //VTK - vtkRenderer *theRenderer = - ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()-> - getRightFrame()->getViewFrame())->getRenderer(); - vtkRenderWindow *renWin = theRenderer->GetRenderWindow(); - - if (mySimulationActors != NULL) - { - - mySimulationActors->InitTraversal(); - vtkActor *ac = mySimulationActors->GetNextActor(); - while (!(ac == NULL)) - { - theRenderer->RemoveActor(ac); - ac = mySimulationActors->GetNextActor(); - } - mySimulationActors->RemoveAllItems(); - } - if (mySimulationActors2D != NULL) - { - mySimulationActors2D->InitTraversal(); - vtkActor2D *ac = mySimulationActors2D->GetNextActor2D(); - while (!(ac == NULL)) - { - theRenderer->RemoveActor2D(ac); - ac = mySimulationActors2D->GetNextActor2D(); - } - mySimulationActors2D->RemoveAllItems(); - } - renWin->Render(); - } + try { + if ( !myComponentMesh->_is_nil() && !aShape->_is_nil() ) { + SMESH::SMESH_Mesh_var aMesh = myComponentMesh->CreateMesh( aShape ); + if ( !aMesh->_is_nil() ) { + SALOMEDS::SObject_var SM = smeshGUI->myStudy->FindObjectIOR( _orb->object_to_string( aMesh ) ); + myStudyAPI.SetName( SM, NameMesh ); + return SMESH::SMESH_Mesh::_narrow(aMesh); + } + } + } + catch( const SALOME::SALOME_Exception& S_ex ) { + QtCatchCorbaException( S_ex ); + } + return SMESH::SMESH_Mesh::_nil(); } //============================================================================= @@ -445,40 +835,21 @@ void SMESHGUI::EraseSimulationActors() * */ //============================================================================= -SMESH::SMESH_Mesh_ptr SMESHGUI::InitMesh(GEOM::GEOM_Shape_ptr aShape, - QString NameMesh) +SMESH::SMESH_subMesh_ptr SMESHGUI::AddSubMesh( SMESH::SMESH_Mesh_ptr aMesh, + GEOM::GEOM_Shape_ptr aShape, + QString NameMesh ) { - try - { - if (!myComponentMesh->_is_nil() && !aShape->_is_nil()) - { - SMESH::SMESH_Mesh_var aMesh = - myComponentMesh->Init(myComponentGeom, myStudyId, aShape); - - if (!aMesh->_is_nil()) - { - SALOMEDS::SObject_var SM = myStudyAPI.AddNewMesh(aMesh); - myStudyAPI.SetName(SM, NameMesh); - - // GEOM::GEOM_Shape has non-empty StudyShapeId only after AddInStudy operation, - // not after loading from file, so let's use more reliable way to retrieve SObject - Standard_CString ShapeIOR = _orb->object_to_string(aShape); - SALOMEDS::SObject_var SObject = - myStudy->FindObjectIOR(ShapeIOR); - if (!SObject->_is_nil() && !SM->_is_nil()) - { - myStudyAPI.SetShape(SM, SObject); - } - return SMESH::SMESH_Mesh::_narrow(aMesh); - } - } - } - catch(const SALOME::SALOME_Exception & S_ex) - { - QtCatchCorbaException(S_ex); - } - myActiveStudy->updateObjBrowser(true); - return SMESH::SMESH_Mesh::_nil(); + SMESH::SMESH_subMesh_var aSubMesh; + try { + if ( !aMesh->_is_nil() && !aShape->_is_nil() ) + // create sub mesh + aSubMesh = SMESH::SMESH_subMesh::_duplicate( aMesh->GetSubMesh( aShape, NameMesh.latin1() ) ); //VSR: published automatically + } + catch( const SALOME::SALOME_Exception& S_ex ) { + QtCatchCorbaException( S_ex ); + aSubMesh = SMESH::SMESH_subMesh::_nil(); + } + return aSubMesh._retn(); } //============================================================================= @@ -486,40 +857,22 @@ SMESH::SMESH_Mesh_ptr SMESHGUI::InitMesh(GEOM::GEOM_Shape_ptr aShape, * */ //============================================================================= -SMESH::SMESH_subMesh_ptr SMESHGUI::AddSubMesh(SMESH::SMESH_Mesh_ptr aMesh, - GEOM::GEOM_Shape_ptr aShape, QString NameMesh) +SMESH::SMESH_Group_ptr SMESHGUI::AddGroup( SMESH::SMESH_Mesh_ptr aMesh, + SMESH::ElementType aType, + QString aName ) { - try - { - SMESH::SMESH_subMesh_var aSubMesh = aMesh->GetElementsOnShape(aShape); - SALOMEDS::SObject_var SO_Mesh = myStudyAPI.FindMesh(aMesh); - Standard_CString ShapeIOR = _orb->object_to_string(aShape); - SALOMEDS::SObject_var SO_GeomShape = myStudy->FindObjectIOR(ShapeIOR); - - if (!SO_GeomShape->_is_nil() && !SO_Mesh->_is_nil() && - !aSubMesh->_is_nil() && !aMesh->_is_nil()) - { - SALOMEDS::SObject_var SO = - myStudyAPI.AddSubMeshOnShape(SO_Mesh, SO_GeomShape, aSubMesh, - aShape->ShapeType()); - myStudyAPI.SetName(SO, NameMesh); - - SMESH_Actor *amesh = SMESH_Actor::New(); - Handle(SALOME_InteractiveObject) IO = - new SALOME_InteractiveObject(SO->GetID(), "MESH", - strdup(NameMesh)); - amesh->setIO(IO); - amesh->setName(strdup(NameMesh)); - DisplayActor(amesh, false); - return SMESH::SMESH_subMesh::_narrow(aSubMesh); - } - } - catch(const SALOME::SALOME_Exception & S_ex) - { - QtCatchCorbaException(S_ex); - } - myActiveStudy->updateObjBrowser(true); - return SMESH::SMESH_subMesh::_nil(); + SMESH::SMESH_Group_var aGroup; + try { + if ( !aMesh->_is_nil() ) + // create group + aGroup = SMESH::SMESH_Group::_duplicate( aMesh->CreateGroup( aType, strdup(aName) ) ); //VSR: published automatically + } + catch( const SALOME::SALOME_Exception& S_ex ) { + QtCatchCorbaException( S_ex ); + aGroup = SMESH::SMESH_Group::_nil(); + } + myActiveStudy->updateObjBrowser( true ); + return aGroup._retn(); } //============================================================================= @@ -527,342 +880,247 @@ SMESH::SMESH_subMesh_ptr SMESHGUI::AddSubMesh(SMESH::SMESH_Mesh_ptr aMesh, * */ //============================================================================= -SMESH::SMESH_Hypothesis_ptr SMESHGUI::CreateHypothesis(QString TypeHypothesis, - QString NameHypothesis) -{ - SMESH::SMESH_Hypothesis_var Hyp; - try - { - Hyp = myComponentMesh->CreateHypothesis(TypeHypothesis, myStudyId); - if (!Hyp->_is_nil()) - { - SALOMEDS::SObject_var SHyp = myStudyAPI.AddNewHypothesis(Hyp); - myStudyAPI.SetName(SHyp, NameHypothesis); - } - } - catch(const SALOME::SALOME_Exception & S_ex) - { - QtCatchCorbaException(S_ex); - } - return SMESH::SMESH_Hypothesis::_narrow(Hyp); +static void addMap( const map& theMap, + map& toMap) +{ + map::const_iterator it; + for ( it = theMap.begin(); it != theMap.end(); it++ ) + toMap.insert( *it ); } + //============================================================================= /*! - * + * InitAvailableHypotheses (read from resource XML file) */ //============================================================================= -void SMESHGUI::AddHypothesisOnMesh(SMESH::SMESH_Mesh_ptr aMesh, - SMESH::SMESH_Hypothesis_ptr aHyp) +void SMESHGUI::InitAvailableHypotheses () { - if (!aMesh->_is_nil()) - { - QApplication::setOverrideCursor(Qt::waitCursor); - SALOMEDS::SObject_var SM = myStudyAPI.FindMesh(aMesh); - GEOM::GEOM_Shape_var aShape = myStudyAPI.GetShapeOnMeshOrSubMesh(SM); - try - { - bool res = aMesh->AddHypothesis(aShape, aHyp); - if (res) - { - SALOMEDS::SObject_var SH = - myStudyAPI.FindHypothesisOrAlgorithms(aHyp); - if (!SM->_is_nil() && !SH->_is_nil()) - { - myStudyAPI.SetHypothesis(SM, SH); - myStudyAPI.ModifiedMesh(SM, false); - } - QApplication::restoreOverrideCursor(); - } - else - { - QApplication::restoreOverrideCursor(); - QAD_MessageBox::warn1(QAD_Application::getDesktop(), - tr("SMESH_WRN_WARNING"), - tr("SMESH_WRN_HYPOTHESIS_ALREADYEXIST"), - tr("SMESH_BUT_YES")); - } - } - catch(const SALOME::SALOME_Exception & S_ex) - { - QtCatchCorbaException(S_ex); - } - } - myActiveStudy->updateObjBrowser(true); - QApplication::restoreOverrideCursor(); + QAD_WaitCursor wc; + if ((myHypothesesMap.begin() == myHypothesesMap.end()) && + (myAlgorithmsMap.begin() == myAlgorithmsMap.end())) + { + // Resource manager + QAD_ResourceMgr* resMgr = QAD_Desktop::createResourceManager(); + if (!resMgr) return; + + // Find name of a resource XML file ("SMESH_Meshers.xml"); + QString HypsXml; + char* cenv = getenv("SMESH_MeshersList"); + if (cenv) + HypsXml.sprintf("%s", cenv); + + QStringList HypsXmlList = QStringList::split( ":", HypsXml, false ); + if (HypsXmlList.count() == 0) + { + QAD_MessageBox::error1(QAD_Application::getDesktop(), + tr("SMESH_WRN_WARNING"), + tr("MESHERS_FILE_NO_VARIABLE"), + tr("SMESH_BUT_OK")); + return; + } + + // loop on files in HypsXml + QString aNoAccessFiles; + for ( int i = 0; i < HypsXmlList.count(); i++ ) { + QString HypsXml = HypsXmlList[ i ]; + + // Find full path to the resource XML file + QString xmlFile = HypsXml + ".xml"; + xmlFile = QAD_Tools::addSlash(resMgr->findFile(xmlFile, HypsXml)) + xmlFile; + + QFile file (QAD_Tools::unix2win(xmlFile)); + if (file.exists() && file.open(IO_ReadOnly)) + { + file.close(); + + SMESHGUI_XmlHandler* myXmlHandler = new SMESHGUI_XmlHandler(); + ASSERT(myXmlHandler); + + QXmlInputSource source (file); + QXmlSimpleReader reader; + reader.setContentHandler(myXmlHandler); + reader.setErrorHandler(myXmlHandler); + bool ok = reader.parse(source); + file.close(); + if (ok) + { + addMap( myXmlHandler->myHypothesesMap, myHypothesesMap ); + addMap( myXmlHandler->myAlgorithmsMap, myAlgorithmsMap ); + } + else + { + QAD_MessageBox::error1(myDesktop, + tr("INF_PARSE_ERROR"), + tr(myXmlHandler->errorProtocol()), + tr("SMESH_BUT_OK")); + } + } + else + { + if (aNoAccessFiles.isEmpty()) + aNoAccessFiles = xmlFile; + else + aNoAccessFiles += ", " + xmlFile; + } + } // end loop + + + if (!aNoAccessFiles.isEmpty()) + { + QString aMess = tr("MESHERS_FILE_CANT_OPEN") + " " + aNoAccessFiles + "\n"; + aMess += tr("MESHERS_FILE_CHECK_VARIABLE"); + wc.stop(); + QAD_MessageBox::warn1(QAD_Application::getDesktop(), + tr("SMESH_WRN_WARNING"), + aMess, + tr("SMESH_BUT_OK")); + wc.start(); + } + } } //============================================================================= /*! - * + * GetAvailableHypotheses (read from resource XML file) */ //============================================================================= -void SMESHGUI:: -RemoveHypothesisOrAlgorithmOnMesh(const Handle(SALOME_InteractiveObject) & - IObject) +QStringList SMESHGUI::GetAvailableHypotheses (const bool isAlgo) { - if (IObject->hasReference()) - { - SMESH::SMESH_Hypothesis_var anHyp; - SALOMEDS::SObject_var SO_Hypothesis = - smeshGUI->myStudy->FindObjectID(IObject->getEntry()); - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::AttributeIOR_var anIOR; - - if (!SO_Hypothesis->_is_nil()) - { - QApplication::setOverrideCursor(Qt::waitCursor); - if (SO_Hypothesis->FindAttribute(anAttr, "AttributeIOR")) - { - anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - anHyp = - SMESH::SMESH_Hypothesis::_narrow(_orb-> - string_to_object(anIOR->Value())); - } - - SALOMEDS::SObject_var SO_Applied_Hypothesis = - smeshGUI->myStudy->FindObjectID(IObject->getReference()); - if (!SO_Applied_Hypothesis->_is_nil()) - { - SALOMEDS::SObject_var MorSM = - smeshGUI->myStudyAPI. - GetMeshOrSubmesh(SO_Applied_Hypothesis); - if (!MorSM->_is_nil()) - { - smeshGUI->myStudyAPI.ModifiedMesh(MorSM, false); - - GEOM::GEOM_Shape_var aShape = - smeshGUI->myStudyAPI.GetShapeOnMeshOrSubMesh(MorSM); - if (!aShape->_is_nil()) - { - if (MorSM->FindAttribute(anAttr, "AttributeIOR")) - { - anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - SMESH::SMESH_Mesh_var aMesh = - SMESH::SMESH_Mesh::_narrow(_orb-> - string_to_object(anIOR->Value())); - SMESH::SMESH_subMesh_var aSubMesh = - SMESH::SMESH_subMesh::_narrow(_orb-> - string_to_object(anIOR->Value())); - if (!aMesh->_is_nil()) - { - bool res = - aMesh->RemoveHypothesis(aShape, anHyp); - if (!res) - { - QApplication::restoreOverrideCursor(); - QAD_MessageBox::warn1(QAD_Application:: - getDesktop(), tr("SMESH_WRN_WARNING"), - tr("SMESH_WRN_HYPOTHESIS_NOTEXIST"), - tr("SMESH_BUT_YES")); - } - } - else if (!aSubMesh->_is_nil()) - { - aMesh = aSubMesh->GetFather(); - if (!aMesh->_is_nil()) - { - bool res = - aMesh->RemoveHypothesis(aShape, anHyp); - if (!res) - { - QApplication::restoreOverrideCursor(); - QAD_MessageBox::warn1(QAD_Application:: - getDesktop(), - tr("SMESH_WRN_WARNING"), - tr("SMESH_WRN_HYPOTHESIS_NOTEXIST"), - tr("SMESH_BUT_YES")); - } - } - } - if (myAutomaticUpdate) - { - SMESH_Actor *Mesh = smeshGUI->ReadScript(aMesh); - if (Mesh != NULL) - { -#ifdef TRACE - Dump(Mesh); -#endif - DisplayActor(Mesh); - DisplayEdges(Mesh); - smeshGUI->ChangeRepresentation(Mesh, - Mesh->getDisplayMode()); - } - } - } - } - } - smeshGUI->myStudyAPI.UnSetHypothesis(SO_Applied_Hypothesis); - } - } - } - else if (IObject->hasEntry()) - { - MESSAGE("IObject entry " << IObject->getEntry())} - QApplication::restoreOverrideCursor(); + QStringList aHypList; + + // Init list of available hypotheses, if needed + InitAvailableHypotheses(); + + // fill list of hypotheses/algorithms + map::iterator anIter; + if (isAlgo) + { + anIter = myAlgorithmsMap.begin(); + for (; anIter != myAlgorithmsMap.end(); anIter++) + { + aHypList.append(((*anIter).first).c_str()); + } + } + else + { + anIter = myHypothesesMap.begin(); + for (; anIter != myHypothesesMap.end(); anIter++) + { + aHypList.append(((*anIter).first).c_str()); + } + } + + return aHypList; } //============================================================================= /*! - * + * GetHypothesisData */ //============================================================================= -void SMESHGUI::RemoveHypothesisOrAlgorithmOnMesh(SALOMEDS::SObject_ptr MorSM, - SMESH::SMESH_Hypothesis_ptr anHyp) +HypothesisData* SMESHGUI::GetHypothesisData (const char* aHypType) { - SALOMEDS::SObject_var AHR, aRef; - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::AttributeIOR_var anIOR; - - if (!MorSM->_is_nil()) - { - GEOM::GEOM_Shape_var aShape = - smeshGUI->myStudyAPI.GetShapeOnMeshOrSubMesh(MorSM); - if (!aShape->_is_nil()) - { - if (MorSM->FindAttribute(anAttr, "AttributeIOR")) - { - anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - SMESH::SMESH_Mesh_var aMesh = - SMESH::SMESH_Mesh::_narrow(_orb->string_to_object(anIOR-> - Value())); - SMESH::SMESH_subMesh_var aSubMesh = - SMESH::SMESH_subMesh::_narrow(_orb->string_to_object(anIOR-> - Value())); - if (!aMesh->_is_nil()) - { - bool res = aMesh->RemoveHypothesis(aShape, anHyp); - if (!res) - { - QApplication::restoreOverrideCursor(); - QAD_MessageBox::warn1(QAD_Application::getDesktop(), - tr("SMESH_WRN_WARNING"), - tr("SMESH_WRN_HYPOTHESIS_NOTEXIST"), - tr("SMESH_BUT_YES")); - } - } - else if (!aSubMesh->_is_nil()) - { - aMesh = aSubMesh->GetFather(); - if (!aMesh->_is_nil()) - { - bool res = aMesh->RemoveHypothesis(aShape, anHyp); - if (!res) - { - QApplication::restoreOverrideCursor(); - QAD_MessageBox::warn1(QAD_Application::getDesktop(), - tr("SMESH_WRN_WARNING"), - tr("SMESH_WRN_HYPOTHESIS_NOTEXIST"), - tr("SMESH_BUT_YES")); - } - } - } - if (myAutomaticUpdate) - { - SMESH_Actor *Mesh = smeshGUI->ReadScript(aMesh); - if (Mesh != NULL) - { -#ifdef TRACE - Dump(Mesh); -#endif - DisplayActor(Mesh); - DisplayEdges(Mesh); - // smeshGUI->ChangeRepresentation( Mesh, Mesh->getDisplayMode() ); - } - } - } - } - - if (MorSM->FindSubObject(2, AHR)) - { - SALOMEDS::ChildIterator_var it = myStudy->NewChildIterator(AHR); - for (; it->More(); it->Next()) - { - SALOMEDS::SObject_var Obj = it->Value(); - if (Obj->ReferencedObject(aRef)) - { - if (aRef->FindAttribute(anAttr, "AttributeIOR")) - { - anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - if (strcmp(anIOR->Value(), - _orb->object_to_string(anHyp)) == 0) - { - smeshGUI->myStudyAPI.UnSetHypothesis(Obj); - break; - } - } - } - } - } - if (MorSM->FindSubObject(3, AHR)) - { - SALOMEDS::ChildIterator_var it = myStudy->NewChildIterator(AHR); - for (; it->More(); it->Next()) - { - SALOMEDS::SObject_var Obj = it->Value(); - if (Obj->ReferencedObject(aRef)) - { - if (aRef->FindAttribute(anAttr, "AttributeIOR")) - { - anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - if (strcmp(anIOR->Value(), - _orb->object_to_string(anHyp)) == 0) - { - smeshGUI->myStudyAPI.UnSetAlgorithm(Obj); - break; - } - } - } - } - } - smeshGUI->myStudyAPI.ModifiedMesh(MorSM, false); - } - QApplication::restoreOverrideCursor(); + HypothesisData* aHypData = 0; + + // Init list of available hypotheses, if needed + InitAvailableHypotheses(); + + if (myHypothesesMap.find(aHypType) == myHypothesesMap.end()) + { + if (myAlgorithmsMap.find(aHypType) != myAlgorithmsMap.end()) + { + aHypData = myAlgorithmsMap[aHypType]; + } + } + else + { + aHypData = myHypothesesMap[aHypType]; + } + return aHypData; } //============================================================================= -/*! - * +/*! + * Get a Hypothesis Creator from a Plugin Library */ //============================================================================= -void SMESHGUI::AddAlgorithmOnMesh(SMESH::SMESH_Mesh_ptr aMesh, - SMESH::SMESH_Hypothesis_ptr aHyp) +SMESHGUI_GenericHypothesisCreator* SMESHGUI::GetHypothesisCreator(const QString& aHypType) { - if (!aMesh->_is_nil()) - { - QApplication::setOverrideCursor(Qt::waitCursor); - SALOMEDS::SObject_var SM = myStudyAPI.FindMesh(aMesh); - GEOM::GEOM_Shape_var aShape = myStudyAPI.GetShapeOnMeshOrSubMesh(SM); - try - { - bool res = aMesh->AddHypothesis(aShape, aHyp); - if (res) - { - SALOMEDS::SObject_var SH = - myStudyAPI.FindHypothesisOrAlgorithms(aHyp); - if (!SM->_is_nil() && !SH->_is_nil()) - { - myStudyAPI.SetAlgorithms(SM, SH); - myStudyAPI.ModifiedMesh(SM, false); - } - } - else - { - QApplication::restoreOverrideCursor(); - QAD_MessageBox::warn1(QAD_Application::getDesktop(), - tr("SMESH_WRN_WARNING"), - tr("SMESH_WRN_ALGORITHM_ALREADYEXIST"), - tr("SMESH_BUT_YES")); - } - } - catch(const SALOME::SALOME_Exception & S_ex) - { - QtCatchCorbaException(S_ex); - } - } - myActiveStudy->updateObjBrowser(true); - QApplication::restoreOverrideCursor(); + char* sHypType = (char*)aHypType.latin1(); + MESSAGE("Get HypothesisCreator for " << sHypType); + + SMESHGUI_GenericHypothesisCreator* aCreator = 0; + + // check, if creator for this hypothesis type already exists + if (myHypCreatorMap.find(sHypType) != myHypCreatorMap.end()) + { + aCreator = myHypCreatorMap[sHypType]; + } + else + { + // 1. Init list of available hypotheses, if needed + InitAvailableHypotheses(); + + // 2. Get names of plugin libraries + HypothesisData* aHypData = GetHypothesisData(sHypType); + if (!aHypData) + { + return aCreator; + } + QString aClientLibName = aHypData->ClientLibName; + QString aServerLibName = aHypData->ServerLibName; + + // 3. Load Client Plugin Library + try + { + // load plugin library + MESSAGE("Loading client meshers plugin library ..."); + void* libHandle = dlopen (aClientLibName, RTLD_LAZY); + if (!libHandle) + { + // report any error, if occured + const char* anError = dlerror(); + MESSAGE(anError); + } + else + { + // get method, returning hypothesis creator + MESSAGE("Find GetHypothesisCreator() method ..."); + typedef SMESHGUI_GenericHypothesisCreator* (*GetHypothesisCreator) \ + (QString aHypType, QString aServerLibName, SMESHGUI* aSMESHGUI); + GetHypothesisCreator procHandle = + (GetHypothesisCreator)dlsym( libHandle, "GetHypothesisCreator" ); + if (!procHandle) + { + MESSAGE("bad hypothesis client plugin library"); + dlclose(libHandle); + } + else + { + // get hypothesis creator + MESSAGE("Get Hypothesis Creator for " << aHypType); + aCreator = procHandle(aHypType, aServerLibName, smeshGUI); + if (!aCreator) + { + MESSAGE("no such a hypothesis in this plugin"); + } + else + { + // map hypothesis creator to a hypothesis name + myHypCreatorMap[sHypType] = aCreator; + } + } + } + } + catch (const SALOME::SALOME_Exception& S_ex) + { + QtCatchCorbaException(S_ex); + } + } + + return aCreator; } //============================================================================= @@ -870,48 +1128,39 @@ void SMESHGUI::AddAlgorithmOnMesh(SMESH::SMESH_Mesh_ptr aMesh, * */ //============================================================================= -void SMESHGUI::AddHypothesisOnSubMesh(SMESH::SMESH_subMesh_ptr aSubMesh, - SMESH::SMESH_Hypothesis_ptr aHyp) +SMESH::SMESH_Hypothesis_ptr SMESHGUI::CreateHypothesis (const QString& aHypType, + const QString& aHypName, + const bool isAlgo) { - if (!aSubMesh->_is_nil()) - { - QApplication::setOverrideCursor(Qt::waitCursor); - try - { - SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather(); - SALOMEDS::SObject_var SsubM = myStudyAPI.FindSubMesh(aSubMesh); - GEOM::GEOM_Shape_var aShape = - myStudyAPI.GetShapeOnMeshOrSubMesh(SsubM); - if (!aMesh->_is_nil()) - { - bool res = aMesh->AddHypothesis(aShape, aHyp); - if (res) - { - SALOMEDS::SObject_var SH = - myStudyAPI.FindHypothesisOrAlgorithms(aHyp); - if (!SsubM->_is_nil() && !SH->_is_nil()) - { - myStudyAPI.SetHypothesis(SsubM, SH); - myStudyAPI.ModifiedMesh(SsubM, false); - } - } - else - { - QApplication::restoreOverrideCursor(); - QAD_MessageBox::warn1(QAD_Application::getDesktop(), - tr("SMESH_WRN_WARNING"), - tr("SMESH_WRN_HYPOTHESIS_ALREADYEXIST"), - tr("SMESH_BUT_YES")); - } - } - } - catch(const SALOME::SALOME_Exception & S_ex) - { - QtCatchCorbaException(S_ex); - } - } - myActiveStudy->updateObjBrowser(true); - QApplication::restoreOverrideCursor(); + MESSAGE("Create " << aHypType << " with name " << aHypName); + + SMESH::SMESH_Hypothesis_var Hyp; + + HypothesisData* aHypData = GetHypothesisData((char*)aHypType.latin1()); + QString aServLib = aHypData->ServerLibName; + + try + { + Hyp = myComponentMesh->CreateHypothesis(aHypType, aServLib); + if (!Hyp->_is_nil()) + { + SALOMEDS::SObject_var SHyp = + smeshGUI->myStudy->FindObjectIOR( _orb->object_to_string( Hyp ) ); + if (!SHyp->_is_nil()) + { + if ( !aHypName.isEmpty() ) + myStudyAPI.SetName( SHyp, aHypName ); + myActiveStudy->updateObjBrowser(true); + return Hyp._retn(); + } + } + } + catch (const SALOME::SALOME_Exception & S_ex) + { + QtCatchCorbaException(S_ex); + } + + return SMESH::SMESH_Hypothesis::_nil(); } //============================================================================= @@ -919,48 +1168,48 @@ void SMESHGUI::AddHypothesisOnSubMesh(SMESH::SMESH_subMesh_ptr aSubMesh, * */ //============================================================================= -void SMESHGUI::AddAlgorithmOnSubMesh(SMESH::SMESH_subMesh_ptr aSubMesh, - SMESH::SMESH_Hypothesis_ptr aHyp) +bool SMESHGUI::AddHypothesisOnMesh(SMESH::SMESH_Mesh_ptr aMesh, + SMESH::SMESH_Hypothesis_ptr aHyp) { - if (!aSubMesh->_is_nil()) - { - QApplication::setOverrideCursor(Qt::waitCursor); - try - { - SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather(); - SALOMEDS::SObject_var SsubM = myStudyAPI.FindSubMesh(aSubMesh); - GEOM::GEOM_Shape_var aShape = - myStudyAPI.GetShapeOnMeshOrSubMesh(SsubM); - if (!aMesh->_is_nil()) - { - bool res = aMesh->AddHypothesis(aShape, aHyp); - if (res) - { - SALOMEDS::SObject_var SH = - myStudyAPI.FindHypothesisOrAlgorithms(aHyp); - if (!SsubM->_is_nil() && !SH->_is_nil()) - { - myStudyAPI.SetAlgorithms(SsubM, SH); - myStudyAPI.ModifiedMesh(SsubM, false); - } - } - else - { - QApplication::restoreOverrideCursor(); - QAD_MessageBox::warn1(QAD_Application::getDesktop(), - tr("SMESH_WRN_WARNING"), - tr("SMESH_WRN_ALGORITHM_ALREADYEXIST"), - tr("SMESH_BUT_YES")); - } - } - } - catch(const SALOME::SALOME_Exception & S_ex) - { - QtCatchCorbaException(S_ex); - } - } - myActiveStudy->updateObjBrowser(true); - QApplication::restoreOverrideCursor(); + int res = SMESH::HYP_UNKNOWN_FATAL; + QAD_WaitCursor wc; + + if ( !aMesh->_is_nil() ) { + SALOMEDS::SObject_var SM = myStudyAPI.FindObject( aMesh ); + GEOM::GEOM_Shape_var aShape = myStudyAPI.GetShapeOnMeshOrSubMesh(SM); + try { + res = aMesh->AddHypothesis( aShape, aHyp ); + if ( res < SMESH::HYP_UNKNOWN_FATAL ) { + SALOMEDS::SObject_var SH = myStudyAPI.FindObject(aHyp); + if ( !SM->_is_nil() && !SH->_is_nil() ) { + //myStudyAPI.SetHypothesis(SM, SH); // VSR: published automatically by engine + myStudyAPI.ModifiedMesh(SM, false); + } + } + if ( res >= SMESH::HYP_UNKNOWN_FATAL ) { + wc.stop(); + QAD_MessageBox::error1(QAD_Application::getDesktop(), + tr("SMESH_ERROR"), + tr(QString("SMESH_HYP_%1").arg(res)), + tr("SMESH_BUT_OK")); + wc.start(); + } + else if ( res > SMESH::HYP_OK ) { + wc.stop(); + QAD_MessageBox::warn1(QAD_Application::getDesktop(), + tr("SMESH_WRN_WARNING"), + tr(QString("SMESH_HYP_%1").arg(res)), + tr("SMESH_BUT_OK")); + wc.start(); + } + } + catch( const SALOME::SALOME_Exception& S_ex ) { + wc.stop(); + QtCatchCorbaException( S_ex ); + res = SMESH::HYP_UNKNOWN_FATAL; + } + } + return res < SMESH::HYP_UNKNOWN_FATAL; } //============================================================================= @@ -968,33 +1217,76 @@ void SMESHGUI::AddAlgorithmOnSubMesh(SMESH::SMESH_subMesh_ptr aSubMesh, * */ //============================================================================= -void SMESHGUI::CreateAlgorithm(QString TypeAlgo, QString NameAlgo) +bool SMESHGUI::RemoveHypothesisOrAlgorithmOnMesh + (const Handle(SALOME_InteractiveObject)& IObject) { - SMESH::SMESH_Hypothesis_var Hyp; - try - { - if (TypeAlgo.compare("Regular_1D") == 0) - Hyp = myComponentMesh->CreateHypothesis(TypeAlgo, myStudyId); - else if (TypeAlgo.compare("MEFISTO_2D") == 0) - Hyp = myComponentMesh->CreateHypothesis(TypeAlgo, myStudyId); - else if (TypeAlgo.compare("Quadrangle_2D") == 0) - Hyp = myComponentMesh->CreateHypothesis(TypeAlgo, myStudyId); - else if (TypeAlgo.compare("Hexa_3D") == 0) - Hyp = myComponentMesh->CreateHypothesis(TypeAlgo, myStudyId); - else if (TypeAlgo.compare("NETGEN_3D") == 0) - Hyp = myComponentMesh->CreateHypothesis(TypeAlgo, myStudyId); - - if (!Hyp->_is_nil()) - { - SALOMEDS::SObject_var SHyp = myStudyAPI.AddNewAlgorithms(Hyp); - myStudyAPI.SetName(SHyp, NameAlgo); - } - } - catch(const SALOME::SALOME_Exception & S_ex) - { - QtCatchCorbaException(S_ex); - } - myActiveStudy->updateObjBrowser(true); + int res = SMESH::HYP_UNKNOWN_FATAL; + QAD_WaitCursor wc; + + if (IObject->hasReference()) + { + try { + SMESH::SMESH_Hypothesis_var anHyp; + SALOMEDS::SObject_var SO_Hypothesis = + smeshGUI->myStudy->FindObjectID(IObject->getEntry()); + SALOMEDS::GenericAttribute_var anAttr; + SALOMEDS::AttributeIOR_var anIOR; + + if (!SO_Hypothesis->_is_nil()) { + if (SO_Hypothesis->FindAttribute(anAttr, "AttributeIOR")) { + anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + anHyp = SMESH::SMESH_Hypothesis::_narrow + (_orb->string_to_object(anIOR->Value())); + } + + SALOMEDS::SObject_var SO_Applied_Hypothesis = + smeshGUI->myStudy->FindObjectID(IObject->getReference()); + if (!SO_Applied_Hypothesis->_is_nil()) { + SALOMEDS::SObject_var MorSM = + smeshGUI->myStudyAPI.GetMeshOrSubmesh(SO_Applied_Hypothesis); + if (!MorSM->_is_nil()) { + GEOM::GEOM_Shape_var aShape = + smeshGUI->myStudyAPI.GetShapeOnMeshOrSubMesh(MorSM); + if (!aShape->_is_nil() && MorSM->FindAttribute(anAttr, "AttributeIOR")) { + anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + SMESH::SMESH_Mesh_var aMesh = + SMESH::SMESH_Mesh::_narrow(_orb->string_to_object(anIOR->Value())); + SMESH::SMESH_subMesh_var aSubMesh = + SMESH::SMESH_subMesh::_narrow(_orb->string_to_object(anIOR->Value())); + + if (!aSubMesh->_is_nil()) + aMesh = aSubMesh->GetFather(); + + if (!aMesh->_is_nil()) + { + res = aMesh->RemoveHypothesis(aShape, anHyp); + if ( res < SMESH::HYP_UNKNOWN_FATAL ) + smeshGUI->myStudyAPI.ModifiedMesh(MorSM, false); + if ( res > SMESH::HYP_OK ) { + wc.stop(); + QAD_MessageBox::warn1(QAD_Application::getDesktop(), + tr("SMESH_WRN_WARNING"), + tr(QString("SMESH_HYP_%1").arg(res)), + tr("SMESH_BUT_OK")); + wc.start(); + } + } + } + } + } + } + } + catch( const SALOME::SALOME_Exception& S_ex ) { + wc.stop(); + QtCatchCorbaException( S_ex ); + res = SMESH::HYP_UNKNOWN_FATAL; + } + } + else if (IObject->hasEntry()) + { + MESSAGE("IObject entry " << IObject->getEntry()); + } + return res < SMESH::HYP_UNKNOWN_FATAL; } //============================================================================= @@ -1002,26 +1294,52 @@ void SMESHGUI::CreateAlgorithm(QString TypeAlgo, QString NameAlgo) * */ //============================================================================= -void SMESHGUI::CreateLocalLength(QString TypeHypothesis, QString NameHypothesis, - double Length) +bool SMESHGUI::RemoveHypothesisOrAlgorithmOnMesh(SALOMEDS::SObject_ptr MorSM, + SMESH::SMESH_Hypothesis_ptr anHyp) { - QApplication::setOverrideCursor(Qt::waitCursor); - try - { - SMESH::SMESH_Hypothesis_var Hyp = - SMESH::SMESH_Hypothesis::_narrow(CreateHypothesis(TypeHypothesis, - NameHypothesis)); - SMESH::SMESH_LocalLength_var LL = - SMESH::SMESH_LocalLength::_narrow(Hyp); - if (!LL->_is_nil()) - LL->SetLength(Length); - } - catch(const SALOME::SALOME_Exception & S_ex) - { - QtCatchCorbaException(S_ex); - } - myActiveStudy->updateObjBrowser(true); - QApplication::restoreOverrideCursor(); + SALOMEDS::SObject_var AHR, aRef; + SALOMEDS::GenericAttribute_var anAttr; + SALOMEDS::AttributeIOR_var anIOR; + int res = SMESH::HYP_UNKNOWN_FATAL; + QAD_WaitCursor wc; + + if (!MorSM->_is_nil()) { + try { + GEOM::GEOM_Shape_var aShape = smeshGUI->myStudyAPI.GetShapeOnMeshOrSubMesh(MorSM); + if (!aShape->_is_nil()) { + if (MorSM->FindAttribute(anAttr, "AttributeIOR")) { + anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + SMESH::SMESH_Mesh_var aMesh = + SMESH::SMESH_Mesh::_narrow(_orb->string_to_object(anIOR->Value())); + SMESH::SMESH_subMesh_var aSubMesh = + SMESH::SMESH_subMesh::_narrow(_orb->string_to_object(anIOR->Value())); + + if ( !aSubMesh->_is_nil() ) + aMesh = aSubMesh->GetFather(); + + if (!aMesh->_is_nil()) { + res = aMesh->RemoveHypothesis(aShape, anHyp); + if ( res < SMESH::HYP_UNKNOWN_FATAL ) + smeshGUI->myStudyAPI.ModifiedMesh(MorSM, false); + if ( res > SMESH::HYP_OK ) { + wc.stop(); + QAD_MessageBox::warn1(QAD_Application::getDesktop(), + tr("SMESH_WRN_WARNING"), + tr(QString("SMESH_HYP_%1").arg(res)), + tr("SMESH_BUT_OK")); + wc.start(); + } + } + } + } + } + catch( const SALOME::SALOME_Exception& S_ex ) { + wc.stop(); + QtCatchCorbaException( S_ex ); + res = SMESH::HYP_UNKNOWN_FATAL; + } + } + return res < SMESH::HYP_UNKNOWN_FATAL; } //============================================================================= @@ -1029,27 +1347,48 @@ void SMESHGUI::CreateLocalLength(QString TypeHypothesis, QString NameHypothesis, * */ //============================================================================= -void SMESHGUI::CreateMaxElementArea(QString TypeHypothesis, - QString NameHypothesis, double MaxArea) +bool SMESHGUI::AddAlgorithmOnMesh( SMESH::SMESH_Mesh_ptr aMesh, + SMESH::SMESH_Hypothesis_ptr aHyp ) { - QApplication::setOverrideCursor(Qt::waitCursor); - try - { - SMESH::SMESH_Hypothesis_var Hyp = - SMESH::SMESH_Hypothesis::_narrow(CreateHypothesis(TypeHypothesis, - NameHypothesis)); - SMESH::SMESH_MaxElementArea_var MaxElArea = - SMESH::SMESH_MaxElementArea::_narrow(Hyp); - if (!MaxElArea->_is_nil()) - MaxElArea->SetMaxElementArea(MaxArea); - } - catch(SALOME::SALOME_Exception & S_ex) - { - QtCatchCorbaException(S_ex); - } - - myActiveStudy->updateObjBrowser(true); - QApplication::restoreOverrideCursor(); + int res = SMESH::HYP_UNKNOWN_FATAL; + QAD_WaitCursor wc; + + if ( !aMesh->_is_nil() ) { + SALOMEDS::SObject_var SM = myStudyAPI.FindObject( aMesh ); + GEOM::GEOM_Shape_var aShape = myStudyAPI.GetShapeOnMeshOrSubMesh( SM ); + try { + res = aMesh->AddHypothesis( aShape, aHyp ); + if ( res < SMESH::HYP_UNKNOWN_FATAL ) { + //SALOMEDS::SObject_var SH = myStudyAPI.FindObject( aHyp ); + //if ( !SM->_is_nil() && !SH->_is_nil() ) { + //myStudyAPI.SetAlgorithms(SM, SH); + myStudyAPI.ModifiedMesh( SM, false ); + //} + } + if ( res >= SMESH::HYP_UNKNOWN_FATAL ) { + wc.stop(); + QAD_MessageBox::error1(QAD_Application::getDesktop(), + tr("SMESH_ERROR"), + tr(QString("SMESH_HYP_%1").arg(res)), + tr("SMESH_BUT_OK")); + wc.start(); + } + else if ( res > SMESH::HYP_OK ) { + wc.stop(); + QAD_MessageBox::warn1( QAD_Application::getDesktop(), + tr( "SMESH_WRN_WARNING" ), + tr(QString("SMESH_HYP_%1").arg(res)), + tr( "SMESH_BUT_OK" ) ); + wc.start(); + } + } + catch( const SALOME::SALOME_Exception& S_ex ) { + wc.stop(); + QtCatchCorbaException( S_ex ); + res = SMESH::HYP_UNKNOWN_FATAL; + } + } + return res < SMESH::HYP_UNKNOWN_FATAL; } //============================================================================= @@ -1057,26 +1396,52 @@ void SMESHGUI::CreateMaxElementArea(QString TypeHypothesis, * */ //============================================================================= -void SMESHGUI::CreateMaxElementVolume(QString TypeHypothesis, - QString NameHypothesis, double MaxVolume) +bool SMESHGUI::AddHypothesisOnSubMesh( SMESH::SMESH_subMesh_ptr aSubMesh, + SMESH::SMESH_Hypothesis_ptr aHyp ) { - QApplication::setOverrideCursor(Qt::waitCursor); - try - { - SMESH::SMESH_Hypothesis_var Hyp = - SMESH::SMESH_Hypothesis::_narrow(CreateHypothesis(TypeHypothesis, - NameHypothesis)); - SMESH::SMESH_MaxElementVolume_var MaxElVolume = - SMESH::SMESH_MaxElementVolume::_narrow(Hyp); - if (!MaxElVolume->_is_nil()) - MaxElVolume->SetMaxElementVolume(MaxVolume); - } - catch(const SALOME::SALOME_Exception & S_ex) - { - QtCatchCorbaException(S_ex); - } - myActiveStudy->updateObjBrowser(true); - QApplication::restoreOverrideCursor(); + int res = SMESH::HYP_UNKNOWN_FATAL; + QAD_WaitCursor wc; + + if ( !aSubMesh->_is_nil() ) { + try { + SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather(); + SALOMEDS::SObject_var SsubM = myStudyAPI.FindObject( aSubMesh ); + GEOM::GEOM_Shape_var aShape = myStudyAPI.GetShapeOnMeshOrSubMesh( SsubM ); + if ( !aMesh->_is_nil() && !SsubM->_is_nil() && !aShape->_is_nil() ) { + res = aMesh->AddHypothesis( aShape, aHyp ); + if ( res < SMESH::HYP_UNKNOWN_FATAL ) { + //SALOMEDS::SObject_var SH = myStudyAPI.FindObject(aHyp); + // if (!SsubM->_is_nil() && !SH->_is_nil()) + // { + // myStudyAPI.SetHypothesis(SsubM, SH); + myStudyAPI.ModifiedMesh( SsubM, false ); + // } + } + if ( res >= SMESH::HYP_UNKNOWN_FATAL ) { + wc.stop(); + QAD_MessageBox::error1(QAD_Application::getDesktop(), + tr("SMESH_ERROR"), + tr(QString("SMESH_HYP_%1").arg(res)), + tr("SMESH_BUT_OK")); + wc.start(); + } + else if ( res > SMESH::HYP_OK ) { + wc.stop(); + QAD_MessageBox::warn1(QAD_Application::getDesktop(), + tr( "SMESH_WRN_WARNING" ), + tr(QString("SMESH_HYP_%1").arg(res)), + tr( "SMESH_BUT_OK" ) ); + wc.start(); + } + } + } + catch( const SALOME::SALOME_Exception& S_ex ) { + wc.stop(); + QtCatchCorbaException( S_ex ); + res = SMESH::HYP_UNKNOWN_FATAL; + } + } + return res < SMESH::HYP_UNKNOWN_FATAL; } //============================================================================= @@ -1084,26 +1449,51 @@ void SMESHGUI::CreateMaxElementVolume(QString TypeHypothesis, * */ //============================================================================= -void SMESHGUI::CreateNbSegments(QString TypeHypothesis, QString NameHypothesis, - int nbSegments) +bool SMESHGUI::AddAlgorithmOnSubMesh( SMESH::SMESH_subMesh_ptr aSubMesh, + SMESH::SMESH_Hypothesis_ptr aHyp ) { - QApplication::setOverrideCursor(Qt::waitCursor); - try - { - SMESH::SMESH_Hypothesis_var Hyp = - SMESH::SMESH_Hypothesis::_narrow(CreateHypothesis(TypeHypothesis, - NameHypothesis)); - SMESH::SMESH_NumberOfSegments_var NbS = - SMESH::SMESH_NumberOfSegments::_narrow(Hyp); - if (!NbS->_is_nil()) - NbS->SetNumberOfSegments(nbSegments); - } - catch(const SALOME::SALOME_Exception & S_ex) - { - QtCatchCorbaException(S_ex); - } - myActiveStudy->updateObjBrowser(true); - QApplication::restoreOverrideCursor(); + int res = SMESH::HYP_UNKNOWN_FATAL; + QAD_WaitCursor wc; + + if ( !aSubMesh->_is_nil() ) { + try { + SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather(); + SALOMEDS::SObject_var SsubM = myStudyAPI.FindObject(aSubMesh); + GEOM::GEOM_Shape_var aShape = myStudyAPI.GetShapeOnMeshOrSubMesh(SsubM); + if ( !aMesh->_is_nil() && !SsubM->_is_nil() && !aShape->_is_nil() ) { + res = aMesh->AddHypothesis( aShape, aHyp ); + if ( res < SMESH::HYP_UNKNOWN_FATAL ) { + //SALOMEDS::SObject_var SH = myStudyAPI.FindObject(aHyp); + //if (!SsubM->_is_nil() && !SH->_is_nil()) { + //myStudyAPI.SetAlgorithms(SsubM, SH); + myStudyAPI.ModifiedMesh( SsubM, false ); + //} + } + if ( res >= SMESH::HYP_UNKNOWN_FATAL ) { + wc.stop(); + QAD_MessageBox::error1(QAD_Application::getDesktop(), + tr("SMESH_ERROR"), + tr(QString("SMESH_HYP_%1").arg(res)), + tr("SMESH_BUT_OK")); + wc.start(); + } + else if ( res > SMESH::HYP_OK ) { + wc.stop(); + QAD_MessageBox::warn1(QAD_Application::getDesktop(), + tr( "SMESH_WRN_WARNING" ), + tr(QString("SMESH_HYP_%1").arg(res)), + tr( "SMESH_BUT_OK" ) ); + wc.start(); + } + } + } + catch( const SALOME::SALOME_Exception& S_ex ) { + wc.stop(); + QtCatchCorbaException( S_ex ); + res = SMESH::HYP_UNKNOWN_FATAL; + } + } + return res < SMESH::HYP_UNKNOWN_FATAL; } //============================================================================= @@ -1131,38 +1521,23 @@ int SMESHGUI::GetNameOfSelectedIObjects(SALOME_Selection * Sel, QString & aName) * */ //============================================================================= -int SMESHGUI::GetNameOfSelectedNodes(SALOME_Selection * Sel, QString & aName) -{ - int nbNodes = 0; - int nbSel = Sel->IObjectCount(); - if (nbSel == 1) - { - Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject(); - if (!IObject->hasEntry()) - return -1; - - Standard_Boolean res; - SMESH_Actor *ac = FindActorByEntry(IObject->getEntry(), res, true); - if (!res) - return -1; - - TColStd_MapOfInteger MapIndex; - Sel->GetIndex(IObject, MapIndex); - TColStd_MapIteratorOfMapOfInteger ite(MapIndex); - aName = " "; - nbNodes = MapIndex.Extent(); - for (; ite.More(); ite.Next()) - { - aName = - aName + QString("%1").arg(ac->GetIdSMESHDSNode(ite.Key())) + - " "; - } - } - else - { - aName = ""; - } - return nbNodes; +int SMESHGUI::GetNameOfSelectedNodes(SALOME_Selection * Sel, QString & aName){ + aName = ""; + if(Sel->IObjectCount() == 1){ + Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject(); + if(IObject->hasEntry()){ + if(SMESH_Actor *anActor = ::FindActorByEntry(IObject->getEntry())){ + TColStd_MapOfInteger MapIndex; + Sel->GetIndex(IObject, MapIndex); + TColStd_MapIteratorOfMapOfInteger ite(MapIndex); + for(; ite.More(); ite.Next()){ + aName += QString(" %1").arg(anActor->GetNodeObjId(ite.Key())); + } + return MapIndex.Extent(); + } + } + } + return -1; } //============================================================================= @@ -1170,77 +1545,78 @@ int SMESHGUI::GetNameOfSelectedNodes(SALOME_Selection * Sel, QString & aName) * */ //============================================================================= -int SMESHGUI::GetNameOfSelectedElements(SALOME_Selection * Sel, QString & aName) -{ - int nbElements = 0; - int nbSel = Sel->IObjectCount(); - if (nbSel == 1) - { - Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject(); - if (!IObject->hasEntry()) - return -1; +int SMESHGUI::GetNameOfSelectedElements(SALOME_Selection * Sel, QString & aName){ + aName = ""; + if(Sel->IObjectCount() == 1){ + Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject(); + if(IObject->hasEntry()){ + if(SMESH_Actor *anActor = ::FindActorByEntry(IObject->getEntry())){ + TColStd_MapOfInteger MapIndex; + Sel->GetIndex(IObject, MapIndex); + TColStd_MapIteratorOfMapOfInteger ite(MapIndex); + std::vector aList; + for(; ite.More(); ite.Next()){ + int aVtkId = ite.Key(); + int anObjId = anActor->GetElemObjId(aVtkId); + std::vector::iterator found = find(aList.begin(), aList.end(), anObjId); + // MESSAGE("GetNameOfSelectedElements(): VTK Id = " << aVtkId << ", OBJECT Id = " << anObjId); + if (found == aList.end()) { + aList.push_back(anObjId); + aName += QString(" %1").arg(anObjId); + } + } + return aList.size(); + } + } + } + return -1; +} - Standard_Boolean res; - SMESH_Actor *ac = FindActorByEntry(IObject->getEntry(), res, true); - if (!res) - return -1; - TColStd_MapOfInteger MapIndex; - Sel->GetIndex(IObject, MapIndex); - TColStd_MapIteratorOfMapOfInteger ite(MapIndex); - aName = " "; - nbElements = MapIndex.Extent(); - MESSAGE("GetNameOfSelectedElements(): number = " << nbElements); - for (; ite.More(); ite.Next()) - { - int idVTK = ite.Key(); - MESSAGE("GetNameOfSelectedElements(): VTK Id = " << idVTK); - aName = - aName + QString("%1").arg(ac->GetIdSMESHDSElement(idVTK)) + " "; - } - } - else - { - aName = ""; - } - return nbElements; +//============================================================================= +/*! + * + */ +//============================================================================= +int SMESHGUI::GetNameOfSelectedEdges(SALOME_Selection * Sel, QString & aName){ + aName = ""; + if(Sel->IObjectCount() == 1){ + Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject(); + if(IObject->hasEntry()){ + if(SMESH_Actor *anActor = ::FindActorByEntry(IObject->getEntry())){ + TColStd_MapOfInteger MapIndex; + Sel->GetIndex(IObject, MapIndex); + TColStd_MapIteratorOfMapOfInteger ite(MapIndex); + for(; ite.More(); ite.Next()){ + aName += QString(" %1").arg(ite.Key()); + } + return MapIndex.Extent(); + } + } + } + return -1; } + //============================================================================= /*! * */ //============================================================================= -int SMESHGUI::GetNameOfSelectedEdges(SALOME_Selection * Sel, QString & aName) +SMESH_Actor *SMESHGUI::FindActorByEntry(QString theEntry, + Standard_Boolean & theResult, + bool onlyInActiveView) { - int nbElements = 0; - int nbSel = Sel->IObjectCount(); - if (nbSel == 1) - { - Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject(); - if (!IObject->hasEntry()) - return -1; - - Standard_Boolean res; - SMESH_Actor *ac = FindActorByEntry(IObject->getEntry(), res, true); - if (!res) - return -1; - - TColStd_MapOfInteger MapIndex; - Sel->GetIndex(IObject, MapIndex); - TColStd_MapIteratorOfMapOfInteger ite(MapIndex); - aName = " "; - nbElements = MapIndex.Extent(); - for (; ite.More(); ite.Next()) - { - aName = aName + QString("%1").arg(ite.Key()) + " "; - } - } - else - { - aName = ""; - } - return nbElements; + theResult = false; + int aNbStudyFrames = myActiveStudy->getStudyFramesCount(); + for (int i = 0; i < aNbStudyFrames; i++){ + QAD_StudyFrame *aStudyFrame = myActiveStudy->getStudyFrame(i); + if(SMESH_Actor *anActor = ::FindActorByEntry(aStudyFrame,theEntry.latin1())){ + theResult = true; + return anActor; + } + } + return NULL; } //============================================================================= @@ -1248,54 +1624,20 @@ int SMESHGUI::GetNameOfSelectedEdges(SALOME_Selection * Sel, QString & aName) * */ //============================================================================= -SMESH_Actor *SMESHGUI::FindActorByEntry(QString entry, - Standard_Boolean & testResult, bool onlyInActiveView) +SMESH_Actor* SMESHGUI::FindActor(CORBA::Object_ptr theObj, + Standard_Boolean & theResult, + bool theOnlyInActiveView) { - int nbSf = myActiveStudy->getStudyFramesCount(); - for (int i = 0; i < nbSf; i++) - { - QAD_StudyFrame *sf = myActiveStudy->getStudyFrame(i); - if (sf->getTypeView() == VIEW_VTK) - { - vtkRenderer *Renderer = - ((VTKViewer_ViewFrame *) sf->getRightFrame()->getViewFrame())-> - getRenderer(); - vtkActorCollection *theActors = Renderer->GetActors(); - theActors->InitTraversal(); - vtkActor *ac = theActors->GetNextActor(); - while (!(ac == NULL)) - { - if (ac->IsA("SMESH_Actor")) - { - SMESH_Actor *anActor = SMESH_Actor::SafeDownCast(ac); - if (anActor->hasIO()) - { - Handle(SALOME_InteractiveObject) IO = anActor->getIO(); - if (strcmp(IO->getEntry(), entry) == 0) - { - if (onlyInActiveView) - { - if (sf == myActiveStudy->getActiveStudyFrame()) - { - testResult = true; - return anActor; - } - } - else - { - testResult = true; - return anActor; - } - } - } - } - ac = theActors->GetNextActor(); - } - } - } - - MESSAGE(" Actor Not Found ") testResult = false; - return SMESH_Actor::New(); + theResult = false; + SMESH_Actor* aRes = NULL; + if ( !CORBA::is_nil( theObj ) ) { + SALOMEDS::SObject_var aSObject = SALOMEDS::SObject::_narrow( myStudy->FindObjectIOR( _orb->object_to_string( theObj ) ) ); + if( !aSObject->_is_nil()) { + CORBA::String_var anEntry = aSObject->GetID(); + aRes = FindActorByEntry( anEntry.in(), theResult, theOnlyInActiveView ); + } + } + return aRes; } //============================================================================= @@ -1303,17 +1645,34 @@ SMESH_Actor *SMESHGUI::FindActorByEntry(QString entry, * */ //============================================================================= -SMESH_Actor *SMESHGUI::FindActor(SMESH::SMESH_Mesh_ptr aMesh, - Standard_Boolean & testResult, bool onlyInActiveView) +SMESH::SMESH_Mesh_ptr SMESHGUI::ConvertIOinMesh(const Handle(SALOME_InteractiveObject) & IO, + Standard_Boolean & testResult) { - SALOMEDS::SObject_var SM = myStudyAPI.FindMesh(aMesh); - if (SM->_is_nil()) - { - MESSAGE(" Actor Not Found ") testResult = false; - return SMESH_Actor::New(); - } - - return FindActorByEntry(SM->GetID(), testResult, onlyInActiveView); + SMESH::SMESH_Mesh_var aMesh; + testResult = false; + + /* case SObject */ + if (IO->hasEntry()) + { + SALOMEDS::SObject_var obj = myStudy->FindObjectID(IO->getEntry()); + SALOMEDS::GenericAttribute_var anAttr; + SALOMEDS::AttributeIOR_var anIOR; + if (!obj->_is_nil()) + { + if (obj->FindAttribute(anAttr, "AttributeIOR")) + { + anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + aMesh = + SMESH::SMESH_Mesh::_narrow(_orb->string_to_object(anIOR->Value())); + if (!aMesh->_is_nil()) + { + testResult = true; + return SMESH::SMESH_Mesh::_duplicate(aMesh); + } + } + } + } + return SMESH::SMESH_Mesh::_nil(); } //============================================================================= @@ -1321,36 +1680,33 @@ SMESH_Actor *SMESHGUI::FindActor(SMESH::SMESH_Mesh_ptr aMesh, * */ //============================================================================= -SMESH::SMESH_Mesh_ptr SMESHGUI:: -ConvertIOinMesh(const Handle(SALOME_InteractiveObject) & IO, - Standard_Boolean & testResult) +SMESH::SMESH_subMesh_ptr SMESHGUI::ConvertIOinSubMesh(const Handle(SALOME_InteractiveObject) & IO, + Standard_Boolean & testResult) { - SMESH::SMESH_Mesh_var aMesh; - testResult = false; - - /* case SObject */ - if (IO->hasEntry()) - { - SALOMEDS::SObject_var obj = myStudy->FindObjectID(IO->getEntry()); - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::AttributeIOR_var anIOR; - if (!obj->_is_nil()) - { - if (obj->FindAttribute(anAttr, "AttributeIOR")) - { - anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - aMesh = - SMESH::SMESH_Mesh::_narrow(_orb->string_to_object(anIOR-> - Value())); - if (!aMesh->_is_nil()) - { - testResult = true; - return SMESH::SMESH_Mesh::_duplicate(aMesh); - } - } - } - } - return SMESH::SMESH_Mesh::_nil(); + SMESH::SMESH_subMesh_var aSubMesh; + testResult = false; + + /* case SObject */ + if (IO->hasEntry()) + { + SALOMEDS::SObject_var obj = myStudy->FindObjectID(IO->getEntry()); + SALOMEDS::GenericAttribute_var anAttr; + SALOMEDS::AttributeIOR_var anIOR; + if (!obj->_is_nil()) + { + if (obj->FindAttribute(anAttr, "AttributeIOR")) + { + anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + aSubMesh = SMESH::SMESH_subMesh::_narrow(_orb->string_to_object(anIOR->Value())); + if (!aSubMesh->_is_nil()) + { + testResult = true; + return SMESH::SMESH_subMesh::_duplicate(aSubMesh); + } + } + } + } + return SMESH::SMESH_subMesh::_nil(); } //============================================================================= @@ -1358,36 +1714,33 @@ ConvertIOinMesh(const Handle(SALOME_InteractiveObject) & IO, * */ //============================================================================= -SMESH::SMESH_subMesh_ptr SMESHGUI:: -ConvertIOinSubMesh(const Handle(SALOME_InteractiveObject) & IO, - Standard_Boolean & testResult) +SMESH::SMESH_Hypothesis_ptr SMESHGUI::ConvertIOinSMESHHypothesis(const Handle(SALOME_InteractiveObject) & IO, + Standard_Boolean & testResult) { - SMESH::SMESH_subMesh_var aSubMesh; - testResult = false; - - /* case SObject */ - if (IO->hasEntry()) - { - SALOMEDS::SObject_var obj = myStudy->FindObjectID(IO->getEntry()); - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::AttributeIOR_var anIOR; - if (!obj->_is_nil()) - { - if (obj->FindAttribute(anAttr, "AttributeIOR")) - { - anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - aSubMesh = - SMESH::SMESH_subMesh::_narrow(_orb->string_to_object(anIOR-> - Value())); - if (!aSubMesh->_is_nil()) - { - testResult = true; - return SMESH::SMESH_subMesh::_duplicate(aSubMesh); - } - } - } - } - return SMESH::SMESH_subMesh::_nil(); + SMESH::SMESH_Hypothesis_var aHyp; + testResult = false; + + /* case SObject */ + if (IO->hasEntry()) + { + SALOMEDS::SObject_var obj = myStudy->FindObjectID(IO->getEntry()); + SALOMEDS::GenericAttribute_var anAttr; + SALOMEDS::AttributeIOR_var anIOR; + if (!obj->_is_nil()) + { + if (obj->FindAttribute(anAttr, "AttributeIOR")) + { + anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + aHyp = SMESH::SMESH_Hypothesis::_narrow(_orb->string_to_object(anIOR->Value())); + if (!aHyp->_is_nil()) + { + testResult = true; + return SMESH::SMESH_Hypothesis::_duplicate(aHyp); + } + } + } + } + return SMESH::SMESH_Hypothesis::_nil(); } //============================================================================= @@ -1395,36 +1748,29 @@ ConvertIOinSubMesh(const Handle(SALOME_InteractiveObject) & IO, * */ //============================================================================= -SMESH::SMESH_Hypothesis_ptr SMESHGUI:: -ConvertIOinSMESHHypothesis(const Handle(SALOME_InteractiveObject) & IO, - Standard_Boolean & testResult) +SMESH::SMESH_Group_ptr SMESHGUI::ConvertIOinSMESHGroup(const Handle(SALOME_InteractiveObject) & IO, + Standard_Boolean & testResult) { - SMESH::SMESH_Hypothesis_var aHyp; - testResult = false; - - /* case SObject */ - if (IO->hasEntry()) - { - SALOMEDS::SObject_var obj = myStudy->FindObjectID(IO->getEntry()); - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::AttributeIOR_var anIOR; - if (!obj->_is_nil()) - { - if (obj->FindAttribute(anAttr, "AttributeIOR")) - { - anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - aHyp = - SMESH::SMESH_Hypothesis::_narrow(_orb-> - string_to_object(anIOR->Value())); - if (!aHyp->_is_nil()) - { - testResult = true; - return SMESH::SMESH_Hypothesis::_duplicate(aHyp); - } - } - } - } - return SMESH::SMESH_Hypothesis::_nil(); + SMESH::SMESH_Group_var aGroup; + testResult = false; + + /* case SObject */ + if (IO->hasEntry()) { + SALOMEDS::SObject_var obj = myStudy->FindObjectID(IO->getEntry()); + SALOMEDS::GenericAttribute_var anAttr; + SALOMEDS::AttributeIOR_var anIOR; + if (!obj->_is_nil()) { + if (obj->FindAttribute(anAttr, "AttributeIOR")) { + anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + aGroup = SMESH::SMESH_Group::_narrow(_orb->string_to_object(anIOR->Value())); + if (!aGroup->_is_nil()) { + testResult = true; + return SMESH::SMESH_Group::_duplicate(aGroup); + } + } + } + } + return SMESH::SMESH_Group::_nil(); } //============================================================================= @@ -1432,34 +1778,29 @@ ConvertIOinSMESHHypothesis(const Handle(SALOME_InteractiveObject) & IO, * */ //============================================================================= -GEOM::GEOM_Shape_ptr SMESHGUI:: -ConvertIOinGEOMShape(const Handle(SALOME_InteractiveObject) & IO, - Standard_Boolean & testResult) +GEOM::GEOM_Shape_ptr SMESHGUI::ConvertIOinGEOMShape(const Handle(SALOME_InteractiveObject) & IO, + Standard_Boolean & testResult) { - GEOM::GEOM_Shape_var aShape; - testResult = false; - - /* case SObject */ - if (IO->hasEntry()) - { - SALOMEDS::SObject_var obj = myStudy->FindObjectID(IO->getEntry()); - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::AttributeIOR_var anIOR; - if (!obj->_is_nil()) - { - if (obj->FindAttribute(anAttr, "AttributeIOR")) - { - anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - aShape = myComponentGeom->GetIORFromString(anIOR->Value()); - if (!aShape->_is_nil()) - { - testResult = true; - return GEOM::GEOM_Shape::_duplicate(aShape); - } - } - } - } - return GEOM::GEOM_Shape::_nil(); + GEOM::GEOM_Shape_var aShape; + testResult = false; + + /* case SObject */ + if (IO->hasEntry()) { + SALOMEDS::SObject_var obj = myStudy->FindObjectID(IO->getEntry()); + SALOMEDS::GenericAttribute_var anAttr; + SALOMEDS::AttributeIOR_var anIOR; + if (!obj->_is_nil()) { + if (obj->FindAttribute(anAttr, "AttributeIOR")) { + anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + aShape = myComponentGeom->GetIORFromString(anIOR->Value()); + if (!aShape->_is_nil()) { + testResult = true; + return GEOM::GEOM_Shape::_duplicate(aShape); + } + } + } + } + return GEOM::GEOM_Shape::_nil(); } //============================================================================= @@ -1467,55 +1808,37 @@ ConvertIOinGEOMShape(const Handle(SALOME_InteractiveObject) & IO, * */ //============================================================================= -void SMESHGUI::SetViewMode(int commandId) -{ - SALOME_Selection *Sel = - SALOME_Selection::Selection(myActiveStudy->getSelection()); - int nbSel = Sel->IObjectCount(); - if (nbSel >= 1) - { - SALOME_ListIteratorOfListIO It(Sel->StoredIObjects()); - for (; It.More(); It.Next()) - { - Handle(SALOME_InteractiveObject) IObject = It.Value(); - if (IObject->hasEntry()) - { - Standard_Boolean res; - SMESH_Actor *ac = - FindActorByEntry(IObject->getEntry(), res, true); - if (res) - { - switch (commandId) - { - case 211: - { - ChangeRepresentation(ac, 0); - break; - } - case 212: - { - ChangeRepresentation(ac, 1); - break; - } - case 213: - { - ChangeRepresentation(ac, 2); - break; - } - case 1132: - { - ChangeRepresentation(ac, 3); - break; - } - } - } - } - } - if (commandId == 1133) - { - ChangeRepresentation(SMESH_Actor::New(), 4); - } - } +void SMESHGUI::SetViewMode(int commandId){ + SALOME_Selection *Sel = SALOME_Selection::Selection(myActiveStudy->getSelection()); + if(Sel->IObjectCount() >= 1){ + SALOME_ListIteratorOfListIO It(Sel->StoredIObjects()); + for(; It.More(); It.Next()){ + Handle(SALOME_InteractiveObject) IObject = It.Value(); + if(IObject->hasEntry()){ + if(SMESH_Actor *anActor = ::FindActorByEntry(IObject->getEntry())){ + switch(commandId){ + case 211: + ChangeRepresentation(anActor,0); + break; + case 212: + ChangeRepresentation(anActor,1); + break; + case 213: + ChangeRepresentation(anActor,2); + break; + case 215: + ChangeRepresentation(anActor,5); + break; + case 1132: + ChangeRepresentation(anActor,3); + break; + } + } + } + } + if(commandId == 1133) + ChangeRepresentation(NULL,4); + } } //============================================================================= @@ -1523,207 +1846,110 @@ void SMESHGUI::SetViewMode(int commandId) * */ //============================================================================= -void SMESHGUI::ChangeRepresentation(SMESH_Actor * ac, int type) -{ - if (ac->DataSource == NULL && type != 4) - return; - - if (type != 4) - { - if (ac->getMapper() == NULL) - { - return; - } - } - switch (type) - { - case 0: - { - QApplication::setOverrideCursor(Qt::waitCursor); - if (ac->getDisplayMode() == 2) - { - bool isColored = ac->getMapper()->GetScalarVisibility(); //SAL3899 - vtkDataSetMapper *meshMapper = - (vtkDataSetMapper *) (ac->getMapper()); - meshMapper->SetInput(ac->DataSource); - meshMapper->SetScalarVisibility(isColored); //SAL3899 - } - ac->setDisplayMode(0); - ac->GetProperty()->SetRepresentationToWireframe(); - // ac->SetActorProperty( ac->GetProperty() ); - QApplication::restoreOverrideCursor(); - break; - } - case 1: - { - QApplication::setOverrideCursor(Qt::waitCursor); - if (ac->getDisplayMode() == 2) - { - bool isColored = ac->getMapper()->GetScalarVisibility(); //SAL3899 - vtkDataSetMapper *meshMapper = - (vtkDataSetMapper *) (ac->getMapper()); - meshMapper->SetInput(ac->DataSource); - meshMapper->SetScalarVisibility(isColored); //SAL3899 - } - ac->setDisplayMode(1); - ac->GetProperty()->SetRepresentationToSurface(); - QApplication::restoreOverrideCursor(); - // ac->SetActorProperty( ac->GetProperty() ); - break; - } - case 2: - { - // if (!(ac->getDisplayMode()==2)) { - // ChangeRepresentation(ac, 1); - QApplication::setOverrideCursor(Qt::waitCursor); - ac->setDisplayMode(2); - bool isColored = ac->getMapper()->GetScalarVisibility(); //SAL3899 - vtkDataSetMapper *meshMapper = (vtkDataSetMapper *) (ac->getMapper()); - vtkShrinkFilter *shrink = vtkShrinkFilter::New(); - shrink->SetInput(ac->DataSource); - shrink->SetShrinkFactor(ac->GetShrinkFactor()); - - meshMapper->SetInput(shrink->GetOutput()); - meshMapper->SetScalarVisibility(isColored); //SAL3899 - ac->SetMapper(meshMapper); - QApplication::restoreOverrideCursor(); - // } - break; - } - case 3: - { - float color[3]; - float edgecolor[3]; - float backfacecolor[3]; - float nodecolor[3]; - ac->GetColor(color[0], color[1], color[2]); -// QColor c(color[0]*255,color[1]*255,color[2]*255); - int c0 = int (color[0] * 255); - int c1 = int (color[1] * 255); - int c2 = int (color[2] * 255); - QColor c(c0, c1, c2); - ac->GetEdgeColor(edgecolor[0], edgecolor[1], edgecolor[2]); -// QColor e(edgecolor[0]*255,edgecolor[1]*255,edgecolor[2]*255); - c0 = int (edgecolor[0] * 255); - c1 = int (edgecolor[1] * 255); - c2 = int (edgecolor[2] * 255); - QColor e(c0, c1, c2); - ac->GetBackfaceProperty()->GetColor(backfacecolor); -// QColor b(backfacecolor[0]*255,backfacecolor[1]*255,backfacecolor[2]*255); - c0 = int (backfacecolor[0] * 255); - c1 = int (backfacecolor[1] * 255); - c2 = int (backfacecolor[2] * 255); - QColor b(c0, c1, c2); - ac->GetNodeColor(nodecolor[0], nodecolor[1], nodecolor[2]); -// QColor n(nodecolor[0]*255, nodecolor[1]*255, nodecolor[2]*255 ) ; - c0 = int (nodecolor[0] * 255); - c1 = int (nodecolor[1] * 255); - c2 = int (nodecolor[2] * 255); - QColor n(c0, c1, c2); - - int Edgewidth = (int)ac->EdgeDevice->GetProperty()->GetLineWidth(); - if (Edgewidth == 0) - Edgewidth = 1; - int intValue = ac->GetNodeSize(); - float Shrink = ac->GetShrinkFactor(); - - SMESHGUI_Preferences_ColorDlg *aDlg = - new SMESHGUI_Preferences_ColorDlg(QAD_Application::getDesktop(), - ""); - aDlg->SetColor(1, c); - aDlg->SetColor(2, e); - aDlg->SetColor(3, n); - aDlg->SetColor(4, b); - aDlg->SetIntValue(1, Edgewidth); - aDlg->SetIntValue(2, intValue); - aDlg->SetIntValue(3, int (Shrink * 100.)); - - if (aDlg->exec()) - { - QApplication::setOverrideCursor(Qt::waitCursor); - QColor color = aDlg->GetColor(1); - QColor edgecolor = aDlg->GetColor(2); - QColor nodecolor = aDlg->GetColor(3); - QColor backfacecolor = aDlg->GetColor(4); - /* actor color and backface color */ - ac->GetProperty()->SetColor(float (color.red()) / 255., - float (color.green()) / 255., float (color.blue()) / 255.); - ac->SetColor(float (color.red()) / 255., - float (color.green()) / 255., float (color.blue()) / 255.); - ac->GetBackfaceProperty()->SetColor(float (backfacecolor.red()) / - 255., float (backfacecolor.green()) / 255., - float (backfacecolor.blue()) / 255.); - - /* edge color */ - ac->EdgeDevice->GetProperty()->SetColor(float (edgecolor.red()) / - 255., float (edgecolor.green()) / 255., - float (edgecolor.blue()) / 255.); - ac->EdgeShrinkDevice->GetProperty()->SetColor(float (edgecolor. - red()) / 255., float (edgecolor.green()) / 255., - float (edgecolor.blue()) / 255.); - ac->SetEdgeColor(float (edgecolor.red()) / 255., - float (edgecolor.green()) / 255., - float (edgecolor.blue()) / 255.); - - /* Shrink factor and size edges */ - ac->SetShrinkFactor(aDlg->GetIntValue(3) / 100.); - ac->EdgeDevice->GetProperty()->SetLineWidth(aDlg->GetIntValue(1)); - ac->EdgeShrinkDevice->GetProperty()->SetLineWidth(aDlg-> - GetIntValue(1)); - - /* Nodes color and size */ - ac->SetNodeColor(float (nodecolor.red()) / 255., - float (nodecolor.green()) / 255., - float (nodecolor.blue()) / 255.); - ac->SetNodeSize(aDlg->GetIntValue(2)); - - if (ac->getDisplayMode() == 2) - { - bool isColored = ac->getMapper()->GetScalarVisibility(); //SAL3899 - vtkDataSetMapper *meshMapper = - (vtkDataSetMapper *) (ac->getMapper()); - meshMapper->SetInput(ac->DataSource); - vtkShrinkFilter *shrink = vtkShrinkFilter::New(); - shrink->SetInput(meshMapper->GetInput()); - shrink->SetShrinkFactor(ac->GetShrinkFactor()); - - meshMapper->SetInput(shrink->GetOutput()); - meshMapper->SetScalarVisibility(isColored); //SAL3899 - ac->SetMapper(meshMapper); - } - } - delete aDlg; - QApplication::restoreOverrideCursor(); - break; - } - case 4: - { - EmitSignalDeactivateDialog(); - SALOME_Selection *Sel = - SALOME_Selection::Selection(myActiveStudy->getSelection()); - SMESHGUI_TransparencyDlg *aDlg = - new SMESHGUI_TransparencyDlg(QAD_Application::getDesktop(), "", - Sel); - break; - } - case 5: - { - QApplication::setOverrideCursor(Qt::waitCursor); - ac->GetProperty()->SetRepresentationToPoints(); - QApplication::restoreOverrideCursor(); - break; - } - } - - QApplication::setOverrideCursor(Qt::waitCursor); - if (myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) - { //VTK - vtkRenderer *theRenderer = - ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()-> - getRightFrame()->getViewFrame())->getRenderer(); - theRenderer->Render(); - } - QApplication::restoreOverrideCursor(); +void SMESHGUI::ChangeRepresentation(SMESH_Actor * theActor, int type){ + switch (type){ + case 0:{ + //theActor->UnShrink(); + theActor->SetRepresentation(SMESH_Actor::eEdge); + break; + } + case 1:{ + //theActor->UnShrink(); + theActor->SetRepresentation(SMESH_Actor::eSurface); + break; + } + case 2:{ + theActor->IsShrunk() ? theActor->UnShrink() : theActor->SetShrink(); + //theActor->SetRepresentation(SMESH_Actor::eSurface); + break; + } + case 5:{ + //theActor->UnShrink(); + theActor->SetRepresentation(SMESH_Actor::ePoint); + break; + } + case 3:{ + float color[3]; + theActor->GetSufaceColor(color[0], color[1], color[2]); + int c0 = int (color[0] * 255); + int c1 = int (color[1] * 255); + int c2 = int (color[2] * 255); + QColor c(c0, c1, c2); + + float edgecolor[3]; + theActor->GetEdgeColor(edgecolor[0], edgecolor[1], edgecolor[2]); + c0 = int (edgecolor[0] * 255); + c1 = int (edgecolor[1] * 255); + c2 = int (edgecolor[2] * 255); + QColor e(c0, c1, c2); + + float backfacecolor[3]; + theActor->GetBackSufaceColor(backfacecolor[0], backfacecolor[1], backfacecolor[2]); + c0 = int (backfacecolor[0] * 255); + c1 = int (backfacecolor[1] * 255); + c2 = int (backfacecolor[2] * 255); + QColor b(c0, c1, c2); + + float nodecolor[3]; + theActor->GetNodeColor(nodecolor[0], nodecolor[1], nodecolor[2]); + c0 = int (nodecolor[0] * 255); + c1 = int (nodecolor[1] * 255); + c2 = int (nodecolor[2] * 255); + QColor n(c0, c1, c2); + + int Edgewidth = (int)theActor->GetLineWidth(); + if(Edgewidth == 0) + Edgewidth = 1; + int intValue = int(theActor->GetNodeSize()); + float Shrink = theActor->GetShrinkFactor(); + + SMESHGUI_Preferences_ColorDlg *aDlg = new SMESHGUI_Preferences_ColorDlg(QAD_Application::getDesktop(),""); + aDlg->SetColor(1, c); + aDlg->SetColor(2, e); + aDlg->SetColor(3, n); + aDlg->SetColor(4, b); + aDlg->SetIntValue(1, Edgewidth); + aDlg->SetIntValue(2, intValue); + aDlg->SetIntValue(3, int(Shrink*100.)); + if(aDlg->exec()){ + QColor color = aDlg->GetColor(1); + QColor edgecolor = aDlg->GetColor(2); + QColor nodecolor = aDlg->GetColor(3); + QColor backfacecolor = aDlg->GetColor(4); + /* actor color and backface color */ + theActor->SetSufaceColor(float (color.red()) / 255., + float (color.green()) / 255., + float (color.blue()) / 255.); + theActor->SetBackSufaceColor(float (backfacecolor.red()) / 255., + float (backfacecolor.green()) / 255., + float (backfacecolor.blue()) / 255.); + + /* edge color */ + theActor->SetEdgeColor(float (edgecolor.red()) / 255., + float (edgecolor.green()) / 255., + float (edgecolor.blue()) / 255.); + + /* Shrink factor and size edges */ + theActor->SetShrinkFactor(aDlg->GetIntValue(3) / 100.); + theActor->SetLineWidth(aDlg->GetIntValue(1)); + + /* Nodes color and size */ + theActor->SetNodeColor(float (nodecolor.red()) / 255., + float (nodecolor.green()) / 255., + float (nodecolor.blue()) / 255.); + theActor->SetNodeSize(aDlg->GetIntValue(2)); + + delete aDlg; + } + break; + } + case 4:{ + EmitSignalDeactivateDialog(); + SMESHGUI_TransparencyDlg *aDlg = new SMESHGUI_TransparencyDlg(QAD_Application::getDesktop(),"",false); + break; + } + } + UpdateView(); } //============================================================================= @@ -1731,15 +1957,8 @@ void SMESHGUI::ChangeRepresentation(SMESH_Actor * ac, int type) * */ //============================================================================= -void SMESHGUI::UpdateView() -{ - if (myActiveStudy->getActiveStudyFrame()->getTypeView() != VIEW_VTK) - return; - - vtkRenderer *theRenderer = - ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()-> - getRightFrame()->getViewFrame())->getRenderer(); - theRenderer->Render(); +void SMESHGUI::UpdateView(){ + ::RepaintCurrentView(); } //============================================================================= @@ -1747,91 +1966,9 @@ void SMESHGUI::UpdateView() * */ //============================================================================= -void SMESHGUI::DisplayActor(SMESH_Actor * ac, bool visibility) -{ - if (myActiveStudy->getActiveStudyFrame()->getTypeView() != VIEW_VTK) - return; - - MESSAGE("DisplayActor(): DataSource = " << ac->DataSource); - - vtkRenderer *theRenderer = - ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()-> - getRightFrame()->getViewFrame())->getRenderer(); - vtkActorCollection *theActors = theRenderer->GetActors(); - theActors->InitTraversal(); - if (theActors->IsItemPresent(ac) == 0) - { - vtkProperty *prop = vtkProperty::New(); - prop->SetColor(QAD_CONFIG->getSetting("SMESH:SettingsFillColorRed"). - toFloat() / 255., - QAD_CONFIG->getSetting("SMESH:SettingsFillColorGreen").toFloat() / - 255., - QAD_CONFIG->getSetting("SMESH:SettingsFillColorBlue").toFloat() / - 255.); - - prop->SetPointSize(QAD_CONFIG->getSetting("SMESH:SettingsNodesSize"). - toInt()); - prop->SetLineWidth(QAD_CONFIG->getSetting("SMESH:SettingsWidth"). - toInt()); - ac->SetProperty(prop); - ac->SetColor(QAD_CONFIG->getSetting("SMESH:SettingsFillColorRed"). - toFloat() / 255., - QAD_CONFIG->getSetting("SMESH:SettingsFillColorGreen").toFloat() / - 255., - QAD_CONFIG->getSetting("SMESH:SettingsFillColorBlue").toFloat() / - 255.); - - // prop->BackfaceCullingOn(); - vtkProperty *backprop = vtkProperty::New(); - backprop->SetColor(QAD_CONFIG-> - getSetting("SMESH:SettingsBackFaceColorRed").toFloat() / 255., - QAD_CONFIG->getSetting("SMESH:SettingsBackFaceColorGreen"). - toFloat() / 255., - QAD_CONFIG->getSetting("SMESH:SettingsBackFaceColorBlue"). - toFloat() / 255.); - ac->SetBackfaceProperty(backprop); - - int intValue = - QAD_CONFIG->getSetting("SMESH:SettingsShrinkCoeff").toInt(); - if (intValue == 0) - intValue = 80; - ac->SetShrinkFactor(intValue / 100.); - - ac->GetMapper()->SetResolveCoincidentTopologyToShiftZBuffer(); - ac->GetMapper()->SetResolveCoincidentTopologyZShift(0.02); - - QString DisplayMode = QAD_CONFIG->getSetting("SMESH:DisplayMode"); - if (DisplayMode.compare("Wireframe") == 0) - { - ac->setDisplayMode(0); - ChangeRepresentation(ac, 0); - } - else if (DisplayMode.compare("Shading") == 0) - { - ac->setDisplayMode(1); - ChangeRepresentation(ac, 1); - } - else if (DisplayMode.compare("Shrink") == 0) - { - ac->setDisplayMode(2); - ChangeRepresentation(ac, 2); - } - theRenderer->AddActor(ac); - } - else - { - if (ac->GetMapper()) - ac->GetMapper()->Update(); - } - -// if ( visibility ) - ac->SetVisibility(visibility); -// ac->VisibilityOn(); -// else -// ac->VisibilityOff(); - - vtkRenderWindow *renWin = theRenderer->GetRenderWindow(); - renWin->Render(); +void SMESHGUI::DisplayActor(SMESH_Actor * theActor, bool theVisibility){ + theActor->SetVisibility(theVisibility); + ::DisplayActor(myActiveStudy->getActiveStudyFrame(),theActor); } //============================================================================= @@ -1839,22 +1976,8 @@ void SMESHGUI::DisplayActor(SMESH_Actor * ac, bool visibility) * */ //============================================================================= -void SMESHGUI::EraseActor(SMESH_Actor * ac) -{ - if (myActiveStudy->getActiveStudyFrame()->getTypeView() != VIEW_VTK) - return; - - vtkRenderer *theRenderer = - ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()-> - getRightFrame()->getViewFrame())->getRenderer(); - - //NRI- : 02/12/2002 : Fixed bugId 882 - // ac->EdgeDevice->VisibilityOff(); - // ac->EdgeShrinkDevice->VisibilityOff(); - // ac->VisibilityOff(); - ac->SetVisibility(false); - - theRenderer->Render(); +void SMESHGUI::EraseActor(SMESH_Actor * theActor){ + theActor->SetVisibility(false); } //============================================================================= @@ -1920,113 +2043,118 @@ QString SMESHGUI::CheckHomogeneousSelection() //============================================================================= QString SMESHGUI::CheckTypeObject(const Handle(SALOME_InteractiveObject) & IO) { - SALOMEDS::SObject_var sobj = - smeshGUI->myActiveStudy->getStudyDocument()->FindObjectID(IO-> - getEntry()); - if (!sobj->_is_nil()) - { - SALOMEDS::SComponent_var scomp = sobj->GetFatherComponent(); - if (strcmp(scomp->GetID(), IO->getEntry()) == 0) - { // component is selected - return "Component"; - } - } - - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); - Sel->ClearIObjects(); - - Handle(SMESH_TypeFilter) aHypFilter = new SMESH_TypeFilter(HYPOTHESIS); - Handle(SMESH_TypeFilter) anAlgoFilter = new SMESH_TypeFilter(ALGORITHM); - Handle(SMESH_TypeFilter) aMeshFilter = new SMESH_TypeFilter(MESH); - Handle(SMESH_TypeFilter) aSubMeshFilter = new SMESH_TypeFilter(SUBMESH); - Handle(SMESH_TypeFilter) aMeshOrSubMeshFilter = - new SMESH_TypeFilter(MESHorSUBMESH); - Handle(SMESH_TypeFilter) aSubMeshVextexFilter = - new SMESH_TypeFilter(SUBMESH_VERTEX); - Handle(SMESH_TypeFilter) aSubMeshEdgeFilter = - new SMESH_TypeFilter(SUBMESH_EDGE); - Handle(SMESH_TypeFilter) aSubMeshFaceFilter = - new SMESH_TypeFilter(SUBMESH_FACE); - Handle(SMESH_TypeFilter) aSubMeshSolidFilter = - new SMESH_TypeFilter(SUBMESH_SOLID); - Handle(SMESH_TypeFilter) aSubMeshCompoundFilter = - new SMESH_TypeFilter(SUBMESH_COMPOUND); - - Sel->AddFilter(aHypFilter); - if (Sel->AddIObject(IO) != -1) - { - Sel->ClearFilters(); - return "Hypothesis"; - } - - Sel->ClearFilters(); - Sel->AddFilter(anAlgoFilter); - if (Sel->AddIObject(IO) != -1) - { - Sel->ClearFilters(); - return "Algorithm"; - } - - Sel->ClearFilters(); - Sel->AddFilter(aMeshFilter); - if (Sel->AddIObject(IO) != -1) - { - Sel->ClearFilters(); - return "Mesh"; - } - - Sel->ClearFilters(); - Sel->AddFilter(aSubMeshFilter); - if (Sel->AddIObject(IO) != -1) - { - Sel->ClearFilters(); - return "SubMesh"; - } - - Sel->ClearFilters(); - Sel->AddFilter(aSubMeshVextexFilter); - if (Sel->AddIObject(IO) != -1) - { - Sel->ClearFilters(); - return "SubMeshVertex"; - } - - Sel->ClearFilters(); - Sel->AddFilter(aSubMeshEdgeFilter); - if (Sel->AddIObject(IO) != -1) - { - Sel->ClearFilters(); - return "SubMeshEdge"; - } - - Sel->ClearFilters(); - Sel->AddFilter(aSubMeshFaceFilter); - if (Sel->AddIObject(IO) != -1) - { - Sel->ClearFilters(); - return "SubMeshFace"; - } + SALOMEDS::SObject_var sobj = smeshGUI->myActiveStudy->getStudyDocument()->FindObjectID(IO->getEntry()); + if (!sobj->_is_nil()) { + SALOMEDS::SComponent_var scomp = sobj->GetFatherComponent(); + if (strcmp(scomp->GetID(), IO->getEntry()) == 0) + { // component is selected + return "Component"; + } + } + + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + Sel->ClearIObjects(); + + Handle(SMESH_TypeFilter) aHypFilter = new SMESH_TypeFilter(HYPOTHESIS); + Handle(SMESH_TypeFilter) anAlgoFilter = new SMESH_TypeFilter(ALGORITHM); + Handle(SMESH_TypeFilter) aMeshFilter = new SMESH_TypeFilter(MESH); + Handle(SMESH_TypeFilter) aSubMeshFilter = new SMESH_TypeFilter(SUBMESH); + Handle(SMESH_TypeFilter) aGroupFilter = new SMESH_TypeFilter(GROUP); + Handle(SMESH_TypeFilter) aMeshOrSubMeshFilter = new SMESH_TypeFilter(MESHorSUBMESH); + Handle(SMESH_TypeFilter) aSubMeshVextexFilter = new SMESH_TypeFilter(SUBMESH_VERTEX); + Handle(SMESH_TypeFilter) aSubMeshEdgeFilter = new SMESH_TypeFilter(SUBMESH_EDGE); + Handle(SMESH_TypeFilter) aSubMeshFaceFilter = new SMESH_TypeFilter(SUBMESH_FACE); + Handle(SMESH_TypeFilter) aSubMeshSolidFilter = new SMESH_TypeFilter(SUBMESH_SOLID); + Handle(SMESH_TypeFilter) aSubMeshCompoundFilter = new SMESH_TypeFilter(SUBMESH_COMPOUND); + + Sel->AddFilter(aHypFilter); + if (Sel->AddIObject(IO) != -1) { + Sel->ClearFilters(); + return "Hypothesis"; + } + + Sel->ClearFilters(); + Sel->AddFilter(anAlgoFilter); + if (Sel->AddIObject(IO) != -1) { + Sel->ClearFilters(); + return "Algorithm"; + } + + Sel->ClearFilters(); + Sel->AddFilter(aMeshFilter); + if (Sel->AddIObject(IO) != -1) { + Sel->ClearFilters(); + return "Mesh"; + } + + Sel->ClearFilters(); + Sel->AddFilter(aSubMeshFilter); + if (Sel->AddIObject(IO) != -1) { + Sel->ClearFilters(); + return "SubMesh"; + } + + Sel->ClearFilters(); + Sel->AddFilter(aGroupFilter); + if (Sel->AddIObject(IO) != -1) { + Sel->ClearFilters(); + return "Group"; + } + + Sel->ClearFilters(); + Sel->AddFilter(aSubMeshVextexFilter); + if (Sel->AddIObject(IO) != -1) { + Sel->ClearFilters(); + return "SubMeshVertex"; + } + + Sel->ClearFilters(); + Sel->AddFilter(aSubMeshEdgeFilter); + if (Sel->AddIObject(IO) != -1) { + Sel->ClearFilters(); + return "SubMeshEdge"; + } + + Sel->ClearFilters(); + Sel->AddFilter(aSubMeshFaceFilter); + if (Sel->AddIObject(IO) != -1) { + Sel->ClearFilters(); + return "SubMeshFace"; + } + + Sel->ClearFilters(); + Sel->AddFilter(aSubMeshSolidFilter); + if (Sel->AddIObject(IO) != -1) { + Sel->ClearFilters(); + return "SubMeshSolid"; + } + + Sel->ClearFilters(); + Sel->AddFilter(aSubMeshCompoundFilter); + if (Sel->AddIObject(IO) != -1) { + Sel->ClearFilters(); + return "SubMeshCompound"; + } + + Sel->ClearFilters(); + Sel->AddIObject(IO); + return "NoType"; +} - Sel->ClearFilters(); - Sel->AddFilter(aSubMeshSolidFilter); - if (Sel->AddIObject(IO) != -1) - { - Sel->ClearFilters(); - return "SubMeshSolid"; - } - Sel->ClearFilters(); - Sel->AddFilter(aSubMeshCompoundFilter); - if (Sel->AddIObject(IO) != -1) - { - Sel->ClearFilters(); - return "SubMeshCompound"; - } +static int isStudyLocked(const SALOMEDS::Study_var& theStudy){ + return theStudy->GetProperties()->IsLocked(); +} - Sel->ClearFilters(); - Sel->AddIObject(IO); - return "NoType"; +static int checkLock(const SALOMEDS::Study_var& theStudy) { + if (isStudyLocked(theStudy)) { + QAD_MessageBox::warn1 ( (QWidget*)QAD_Application::getDesktop(), + QObject::tr("WRN_WARNING"), + QObject::tr("WRN_STUDY_LOCKED"), + QObject::tr("BUT_OK") ); + return true; + } + return false; } //============================================================================= @@ -2036,2584 +2164,1003 @@ QString SMESHGUI::CheckTypeObject(const Handle(SALOME_InteractiveObject) & IO) //============================================================================= bool SMESHGUI::OnGUIEvent(int theCommandID, QAD_Desktop * parent) { - /* Create or retrieve an object SMESHGUI */ - SMESHGUI::GetOrCreateSMESHGUI(parent); - - // NRI : Temporary added - if (smeshGUI->myStudy->GetProperties()->IsLocked()) - { - return false; + SALOMEDS::Study_var aStudy = smeshGUI->myActiveStudy->getStudyDocument(); //Document OCAF de l'etude active + // QAD_Viewer3d* v3d; + OCCViewer_Viewer3d *v3d; + + Handle(AIS_InteractiveContext) ic; + vtkRenderer *Renderer; + vtkRenderWindow *RenWin; + + if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_OCC) { + v3d = ((OCCViewer_ViewFrame *) smeshGUI->myActiveStudy-> + getActiveStudyFrame()->getRightFrame()->getViewFrame())->getViewer(); + ic = v3d->getAISContext(); + } + else if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) { + Renderer = ((VTKViewer_ViewFrame *) smeshGUI->myActiveStudy-> + getActiveStudyFrame()->getRightFrame()->getViewFrame())->getRenderer(); + RenWin = Renderer->GetRenderWindow(); + } + + switch (theCommandID) { + case 33: // DELETE + if(checkLock(aStudy)) break; + smeshGUI->OnEditDelete(); + break; + + case 113: // IMPORT + case 112: + case 111: + { + if(checkLock(aStudy)) break; + //Import_Document(parent, theCommandID); //NBU + Import_Mesh(parent,theCommandID); + break; + } + + case 122: // EXPORT MED + case 121: + case 123: + { + Export_Mesh(parent, theCommandID); + break; + } + + case 200: // SCALAR BAR + { + SALOME_Selection *Sel = SALOME_Selection::Selection( smeshGUI->myActiveStudy->getSelection() ); + if( Sel && Sel->IObjectCount() ) { + Handle(SALOME_InteractiveObject) anIO = Sel->firstIObject(); + if( anIO->hasEntry() ) { + if( SMESH_Actor* anActor = ::FindActorByEntry( anIO->getEntry() ) ) { + anActor->SetControlMode( SMESH_Actor::eNone ); + } + } + } + break; + } + case 201: + { + SALOME_Selection* Sel = SALOME_Selection::Selection( smeshGUI->myActiveStudy->getSelection() ); + SMESHGUI_Preferences_ScalarBarDlg::ScalarBarProperties( parent, Sel ); + break; + } + + case 1133: // DISPLAY MODE : WireFrame, Surface, Shrink + case 1132: + case 215: + case 213: + case 212: + case 211: + { + smeshGUI->SetViewMode(theCommandID); + break; + } + + case 214: // UPDATE + { + if(checkLock(aStudy)) break; + smeshGUI->Update(); + break; + } + + case 300: // ERASE + case 301: // DISPLAY + case 302: // DISPLAY ONLY + { + EDisplaing anAction; + switch(theCommandID){ + case 300: anAction = eErase; break; + case 301: anAction = eDisplay; break; + case 302: anAction = eDisplayOnly; break; + } + + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) { + SALOME_ListIteratorOfListIO It(Sel->StoredIObjects()); + for (; It.More(); It.Next()) { + Handle(SALOME_InteractiveObject) IOS = It.Value(); + if (IOS->hasEntry()) { + ::UpdateView(anAction,IOS->getEntry()); + } + } + } + Sel->ClearIObjects(); + break; + } + + case 400: // NODES + { + if(checkLock(aStudy)) break; + if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) { + smeshGUI->EmitSignalDeactivateDialog(); + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + Sel->ClearIObjects(); + smeshGUI->myDesktop->SetSelectionMode(NodeSelection, true); + smeshGUI->ViewNodes(); + SMESHGUI_NodesDlg *aDlg = new SMESHGUI_NodesDlg(parent, "", Sel); + } + else { + QAD_MessageBox::warn1(QAD_Application::getDesktop(), + tr("SMESH_WRN_WARNING"), + tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + + case 2151: // FILTER + { + if ( smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK ) + { + smeshGUI->EmitSignalDeactivateDialog(); + SMESHGUI_FilterDlg *aDlg = new SMESHGUI_FilterDlg( parent, SMESH::EDGE ); + } + break; + } + + case 405: // MOVE NODE + { + if(checkLock(aStudy)) break; + smeshGUI->myDesktop->SetSelectionMode(NodeSelection, true); + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + SMESHGUI_MoveNodesDlg *aDlg = new SMESHGUI_MoveNodesDlg(parent, "", Sel); + break; + } + + case 701: // COMPUTE MESH + { + if(checkLock(aStudy)) break; + if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) { + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + int nbSel = Sel->IObjectCount(); + if (nbSel != 1){ + break; } - //NRI - - // QAD_Viewer3d* v3d; - OCCViewer_Viewer3d *v3d; - Handle(AIS_InteractiveContext) ic; - vtkRenderer *Renderer; - vtkRenderWindow *RenWin; - - if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == - VIEW_OCC) + SMESH::SMESH_Mesh_var aMesh; + SMESH::SMESH_subMesh_var aSubMesh; + Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject(); + if (IObject->hasEntry()){ + SALOMEDS::SObject_var aMeshSObj = smeshGUI->myStudy->FindObjectID(IObject->getEntry()); + GEOM::GEOM_Shape_var aShape = smeshGUI->myStudyAPI.GetShapeOnMeshOrSubMesh( aMeshSObj ); + if ( aShape->_is_nil() ) { + // imported mesh + break; + } + SALOMEDS::GenericAttribute_var anAttr; + if(!aMeshSObj->_is_nil() && aMeshSObj->FindAttribute(anAttr, "AttributeIOR")){ + SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + MESSAGE("SMESHGUI::OnGUIEvent - Compute mesh : IOR = "<< anIOR->Value()); + CORBA::Object_var anObj; + try{ + anObj = _orb->string_to_object(anIOR->Value()); + if (CORBA::is_nil(anObj)){ + MESSAGE("SMESHGUI::OnGUIEvent - Compute mesh : nil object"); + } + }catch(CORBA::COMM_FAILURE & ex){ + INFOS("SMESHGUI::OnGUIEvent - Compute mesh : exception (1)"); + } + aMesh = SMESH::SMESH_Mesh::_narrow(anObj); + aSubMesh = SMESH::SMESH_subMesh::_narrow(anObj); + if (!aMesh->_is_nil()){ + GEOM::GEOM_Shape_var refShape = smeshGUI->myStudyAPI.GetShapeOnMeshOrSubMesh(aMeshSObj); + if (!refShape->_is_nil()) { + if(!smeshGUI->myComponentMesh->IsReadyToCompute(aMesh,refShape)){ + QAD_MessageBox::warn1(QAD_Application::getDesktop(), + tr("SMESH_WRN_WARNING"), + tr("SMESH_WRN_MISSING_PARAMETERS"), + tr("SMESH_BUT_OK")); + break; + } + try{ + if (smeshGUI->myComponentMesh->Compute(aMesh,refShape)) + smeshGUI->myStudyAPI.ModifiedMesh(aMeshSObj,true); + // TO Do : change icon of all submeshes + } + catch(const SALOME::SALOME_Exception & S_ex){ + QtCatchCorbaException(S_ex); + } + } + }else if(!aSubMesh->_is_nil()){ + aMesh = aSubMesh->GetFather(); + GEOM::GEOM_Shape_var refShape = smeshGUI->myStudyAPI.GetShapeOnMeshOrSubMesh(aMeshSObj); + if(!refShape->_is_nil()){ + bool compute = smeshGUI->myComponentMesh->IsReadyToCompute(aMesh,refShape); + if(!compute){ + QAD_MessageBox::warn1(QAD_Application::getDesktop(), + tr("SMESH_WRN_WARNING"), + tr("SMESH_WRN_MISSING_PARAMETERS"), + tr("SMESH_BUT_OK")); + break; + } + try{ + if ( smeshGUI->myComponentMesh->Compute(aMesh,refShape) ) + smeshGUI->myStudyAPI.ModifiedMesh(aMeshSObj,true); + // TO Do : change icon of all submeshes + }catch(const SALOME::SALOME_Exception & S_ex){ + QtCatchCorbaException(S_ex); + } + } + } + } + } + CORBA::Long anId = smeshGUI->myStudy->StudyId(); + TVisualObjPtr aVisualObj = GetVisualObj(anId,IObject->getEntry()); + if(smeshGUI->myAutomaticUpdate && aVisualObj){ + aVisualObj->Update(); + SMESH_Actor* anActor = ::FindActorByEntry(IObject->getEntry()); + if(!anActor){ + anActor = ::CreateActor(smeshGUI->myStudy,IObject->getEntry()); + if(anActor){ + ::DisplayActor(smeshGUI->myActiveStudy->getActiveStudyFrame(),anActor); //apo + ::FitAll(); + } + } + } + }else{ + QAD_MessageBox::warn1(QAD_Application::getDesktop(), + tr("SMESH_WRN_WARNING"), + tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + + case 702: // ADD SUB MESH + { + if(checkLock(aStudy)) break; + if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) { + smeshGUI->EmitSignalDeactivateDialog(); + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + SMESHGUI_AddSubMeshDlg *aDlg = new SMESHGUI_AddSubMeshDlg(parent, "", Sel); + } + else { + QAD_MessageBox::warn1(QAD_Application::getDesktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + + case 703: // INIT MESH + { + if(checkLock(aStudy)) break; + smeshGUI->EmitSignalDeactivateDialog(); + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + SMESHGUI_InitMeshDlg *aDlg = new SMESHGUI_InitMeshDlg(parent, "", Sel); + break; + } + + case 704: // EDIT Hypothesis + { + if(checkLock(aStudy)) break; + smeshGUI->EmitSignalDeactivateDialog(); + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + SMESHGUI_EditHypothesesDlg *aDlg = new SMESHGUI_EditHypothesesDlg(parent, "", Sel); + break; + } + + case 705: // EDIT Global Hypothesis + { + if(checkLock(aStudy)) break; + smeshGUI->EmitSignalDeactivateDialog(); + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + SMESHGUI_EditHypothesesDlg *aDlg = new SMESHGUI_EditHypothesesDlg(parent, "", Sel); + break; + } + + case 706: // EDIT Local Hypothesis + { + if(checkLock(aStudy)) break; + smeshGUI->EmitSignalDeactivateDialog(); + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + SMESHGUI_EditHypothesesDlg *aDlg = new SMESHGUI_EditHypothesesDlg(parent, "", Sel); + break; + } + + case 406: // ORIENTATION ELEMENTS + { + if(checkLock(aStudy)) break; + smeshGUI->EmitSignalDeactivateDialog(); + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + smeshGUI->myDesktop->SetSelectionMode(FaceSelection, true); + SMESHGUI_OrientationElementsDlg *aDlg = new SMESHGUI_OrientationElementsDlg(parent, "", Sel); + break; + } + + case 407: // DIAGONAL INVERSION + { + if(checkLock(aStudy)) break; + smeshGUI->EmitSignalDeactivateDialog(); + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + Sel->ClearIObjects(); + smeshGUI->myDesktop->SetSelectionMode(EdgeOfCellSelection, true); + SMESHGUI_DiagonalInversionDlg *aDlg = new SMESHGUI_DiagonalInversionDlg(parent, "", Sel); + break; + } + + case 801: // CREATE GROUP + { + if(checkLock(aStudy)) break; + smeshGUI->EmitSignalDeactivateDialog(); + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + int nbSel = Sel->IObjectCount(); + if (nbSel == 1) { + // check if mesh is selected + Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject(); + if (IObject->hasEntry()) { + SALOMEDS::SObject_var aMeshSObj = smeshGUI->myStudy->FindObjectID(IObject->getEntry()); + if (!aMeshSObj->_is_nil()) { + CORBA::Object_var anObj = aMeshSObj->GetObject(); + SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(anObj); + SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(anObj); + if (aMesh->_is_nil() && !aSubMesh->_is_nil()) { + aMesh = aSubMesh->GetFather(); + } + if (!aMesh->_is_nil()) { + SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg(parent, "", Sel, aMesh); + aDlg->show(); + } + } + } + } + break; + } + + case 802: // CONSTRUCT GROUP + { + if(checkLock(aStudy)) break; + smeshGUI->EmitSignalDeactivateDialog(); + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + int nbSel = Sel->IObjectCount(); + if (nbSel == 1) { + // check if submesh is selected + Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject(); + if (IObject->hasEntry()) { + SALOMEDS::SObject_var aSObj = smeshGUI->myStudy->FindObjectID(IObject->getEntry()); + if(!aSObj->_is_nil()) { + SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(aSObj->GetObject()); + if (!aSubMesh->_is_nil()) { + try { + SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather(); + // get submesh elements list by types + SMESH::long_array_var aNodes = aSubMesh->GetElementsByType(SMESH::NODE); + SMESH::long_array_var aEdges = aSubMesh->GetElementsByType(SMESH::EDGE); + SMESH::long_array_var aFaces = aSubMesh->GetElementsByType(SMESH::FACE); + SMESH::long_array_var aVolumes = aSubMesh->GetElementsByType(SMESH::VOLUME); + // create group for each type o elements + QString aName = IObject->getName(); + MESSAGE("SMESHGUI::OnGUIEvent - Construct group on submesh : "<length() << ", edges " << aEdges->length() + << ", faces " << aFaces->length() << ", volumes " << aVolumes->length()); + if (aNodes->length() > 0) { + SMESH::SMESH_Group_var aGroup = smeshGUI->AddGroup(aMesh, SMESH::NODE, aName); + aGroup->Add(aNodes); + } + if (aEdges->length() > 0) { + SMESH::SMESH_Group_var aGroup = smeshGUI->AddGroup(aMesh, SMESH::EDGE, aName); + aGroup->Add(aEdges); + } + if (aFaces->length() > 0) { + SMESH::SMESH_Group_var aGroup = smeshGUI->AddGroup(aMesh, SMESH::FACE, aName); + aGroup->Add(aFaces); + } + if (aVolumes->length() > 0) { + SMESH::SMESH_Group_var aGroup = smeshGUI->AddGroup(aMesh, SMESH::VOLUME, aName); + aGroup->Add(aVolumes); + } + smeshGUI->myActiveStudy->updateObjBrowser(true); + }catch(const SALOME::SALOME_Exception & S_ex){ + QtCatchCorbaException(S_ex); + } + } + } + } + } + break; + } + + case 803: // EDIT GROUP + { + if(checkLock(aStudy)) break; + smeshGUI->EmitSignalDeactivateDialog(); + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + int nbSel = Sel->IObjectCount(); + if (nbSel == 1) { + // check if group is selected + Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject(); + if (IObject->hasEntry()) { + SALOMEDS::SObject_var aSObj = smeshGUI->myStudy->FindObjectID(IObject->getEntry()); + if(!aSObj->_is_nil()) { + SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow(aSObj->GetObject()); + if (!aGroup->_is_nil()) { + SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg(parent, "", Sel, aGroup); + aDlg->show(); + } + } + } + } + break; + } + + case 804: // Add elements to group + { + if(checkLock(aStudy)) break; + if (smeshGUI->myState == 800) { + SMESHGUI_GroupDlg *aDlg = (SMESHGUI_GroupDlg*) smeshGUI->myActiveDialogBox; + if (aDlg) aDlg->onAdd(); + } + break; + } + + case 805: // Remove elements from group + { + if(checkLock(aStudy)) break; + if (smeshGUI->myState == 800) { + SMESHGUI_GroupDlg *aDlg = (SMESHGUI_GroupDlg*) smeshGUI->myActiveDialogBox; + if (aDlg) aDlg->onRemove(); + } + break; + } + + case 900: // MESH INFOS + { + smeshGUI->EmitSignalDeactivateDialog(); + SMESHGUI_MeshInfosDlg *aDlg = new SMESHGUI_MeshInfosDlg(parent, "", false); + break; + } + + case 1001: // AUTOMATIC UPDATE PREFERENCES + { + parent->menuBar()->setItemChecked(1001, !parent->menuBar()->isItemChecked(1001)); + if (parent->menuBar()->isItemChecked(1001)) { + QAD_CONFIG->addSetting("SMESH:AutomaticUpdate", "true"); + smeshGUI->myAutomaticUpdate = true; + } + else { + QAD_CONFIG->addSetting("SMESH:AutomaticUpdate", "false"); + smeshGUI->myAutomaticUpdate = false; + } + break; + } + + case 1003: // MESH PREFERENCES + { + smeshGUI->SetDisplaySettings(); + break; + } + + case 1005: + { + SMESHGUI_Preferences_ScalarBarDlg::ScalarBarPreferences( parent ); + break; + } + + case 1006: + { + SMESHGUI_Preferences_SelectionDlg* aDlg = + new SMESHGUI_Preferences_SelectionDlg(parent); + + QColor aColor; + QString SCr, SCg, SCb; + SCr = QAD_CONFIG->getSetting("SMESH:SettingsPreSelectColorRed"); + SCg = QAD_CONFIG->getSetting("SMESH:SettingsPreSelectColorGreen"); + SCb = QAD_CONFIG->getSetting("SMESH:SettingsPreSelectColorBlue"); + if (!SCr.isEmpty() && !SCg.isEmpty() && !SCb.isEmpty()) + aColor = QColor(SCr.toInt(), SCg.toInt(), SCb.toInt()); + else aColor = Qt::cyan; + aDlg->SetColor(1, aColor); + + SCr = QAD_CONFIG->getSetting("SMESH:SettingsItemSelectColorRed"); + SCg = QAD_CONFIG->getSetting("SMESH:SettingsItemSelectColorGreen"); + SCb = QAD_CONFIG->getSetting("SMESH:SettingsItemSelectColorBlue"); + if (!SCr.isEmpty() && !SCg.isEmpty() && !SCb.isEmpty()) + aColor = QColor(SCr.toInt(), SCg.toInt(), SCb.toInt()); + else aColor = Qt::yellow; + aDlg->SetColor(2, aColor); + + SCr = QAD_CONFIG->getSetting("SMESH:SettingsSelectColorRed"); + SCg = QAD_CONFIG->getSetting("SMESH:SettingsSelectColorGreen"); + SCb = QAD_CONFIG->getSetting("SMESH:SettingsSelectColorBlue"); + if (!SCr.isEmpty() && !SCg.isEmpty() && !SCb.isEmpty()) + aColor = QColor(SCr.toInt(), SCg.toInt(), SCb.toInt()); + else aColor = Qt::white; + aDlg->SetColor(3, aColor); + + QString SW1 = QAD_CONFIG->getSetting("SMESH:SettingsPreSelectWidth"); + if (SW1.isEmpty()) SW1 = "5"; + aDlg->SetWidth(1, SW1.toInt()); + + QString SW2 = QAD_CONFIG->getSetting("SMESH:SettingsItemSelectWidth"); + if (SW2.isEmpty()) SW2 = "5"; + aDlg->SetWidth(2, SW2.toInt()); + + QString SP1 = QAD_CONFIG->getSetting("SMESH:SettingsNodeSelectTol"); + if (SP1.isEmpty()) SP1 = "0.025"; + aDlg->SetPrecision(1, SP1.toDouble()); + + QString SP2 = QAD_CONFIG->getSetting("SMESH:SettingsElementsSelectTol"); + if (SP2.isEmpty()) SP2 = "0.001"; + aDlg->SetPrecision(2, SP2.toDouble()); + + if (aDlg->exec()) { + QColor aPreColor = aDlg->GetColor(1); + QAD_CONFIG->addSetting("SMESH:SettingsPreSelectColorRed", aPreColor.red()); + QAD_CONFIG->addSetting("SMESH:SettingsPreSelectColorGreen", aPreColor.green()); + QAD_CONFIG->addSetting("SMESH:SettingsPreSelectColorBlue", aPreColor.blue()); + + QColor aSelColor = aDlg->GetColor(2); + QAD_CONFIG->addSetting("SMESH:SettingsItemSelectColorRed", aSelColor.red()); + QAD_CONFIG->addSetting("SMESH:SettingsItemSelectColorGreen", aSelColor.green()); + QAD_CONFIG->addSetting("SMESH:SettingsItemSelectColorBlue", aSelColor.blue()); + + QColor aHiColor = aDlg->GetColor(3); + QAD_CONFIG->addSetting("SMESH:SettingsSelectColorRed", aHiColor.red()); + QAD_CONFIG->addSetting("SMESH:SettingsSelectColorGreen", aHiColor.green()); + QAD_CONFIG->addSetting("SMESH:SettingsSelectColorBlue", aHiColor.blue()); + + int aPreWidth = aDlg->GetWidth(1); + QAD_CONFIG->addSetting("SMESH:SettingsPreSelectWidth", aPreWidth); + int aSelWidth = aDlg->GetWidth(2); + QAD_CONFIG->addSetting("SMESH:SettingsItemSelectWidth", aSelWidth); + + double aTolNodes = aDlg->GetPrecision(1); + QAD_CONFIG->addSetting("SMESH:SettingsNodeSelectTol", aTolNodes); + double aTolItems = aDlg->GetPrecision(2); + QAD_CONFIG->addSetting("SMESH:SettingsElementsSelectTol", aTolItems); + + // update current study settings + ::UpdateSelectionProp(); + + QAD_StudyFrame* studyFrame = smeshGUI->myActiveStudy->getActiveStudyFrame(); + if (studyFrame->getTypeView() == VIEW_VTK) { + VTKViewer_ViewFrame* aViewFrame = GetVtkViewFrame(studyFrame); + // update VTK viewer properties + VTKViewer_RenderWindowInteractor* anInteractor = aViewFrame->getRWInteractor(); + if (anInteractor) { + anInteractor->SetSelectionProp(aSelColor.red()/255., aSelColor.green()/255., + aSelColor.blue()/255., aSelWidth); + anInteractor->SetSelectionTolerance(aTolNodes, aTolItems); + VTKViewer_InteractorStyleSALOME* aStyle = anInteractor->GetInteractorStyleSALOME(); + if (aStyle) + aStyle->setPreselectionProp(aPreColor.red()/255., aPreColor.green()/255., + aPreColor.blue()/255., aPreWidth); + } + // update actors + vtkRenderer* aRenderer = aViewFrame->getRenderer(); + vtkActorCollection *aCollection = aRenderer->GetActors(); + aCollection->InitTraversal(); + while(vtkActor *anAct = aCollection->GetNextActor()){ + if(SMESH_Actor *anActor = dynamic_cast(anAct)){ + anActor->SetHighlightColor(aHiColor.red()/255., aHiColor.green()/255., + aHiColor.blue()/255.); + anActor->SetPreHighlightColor(aPreColor.red()/255., aPreColor.green()/255., + aPreColor.blue()/255.); + } + } + } + } + + break; + } + + case 1100: // EDIT HYPOTHESIS + { + if(checkLock(aStudy)) break; + SALOME_Selection *Sel = + SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + int nbSel = Sel->IObjectCount(); + + if (nbSel == 1) { + Standard_Boolean res; + SMESH::SMESH_Hypothesis_var Hyp = + smeshGUI->ConvertIOinSMESHHypothesis(Sel->firstIObject(), res); + + /* Look for all mesh objects that have this hypothesis affected in order to flag as ModifiedMesh */ + /* At end below '...->updateObjBrowser(true)' will change icon of mesh objects */ + /* Warning : however by internal mechanism all subMeshes icons are changed ! */ + if ( res ) + { + char* sName = Hyp->GetName(); + SMESHGUI_GenericHypothesisCreator* aCreator = smeshGUI->GetHypothesisCreator(sName); + if (aCreator) + { + aCreator->EditHypothesis(Hyp); + } + else + { + // report error + } + } + } + break; + } + + case 1101: // RENAME + { + if(checkLock(aStudy)) break; + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + SALOME_ListIteratorOfListIO It(Sel->StoredIObjects()); + for (; It.More(); It.Next()) { + Handle(SALOME_InteractiveObject) IObject = It.Value(); + + SALOMEDS::SObject_var obj = smeshGUI->myStudy->FindObjectID(IObject->getEntry()); + SALOMEDS::GenericAttribute_var anAttr; + SALOMEDS::AttributeName_var aName; + if (!obj->_is_nil()) { + if (obj->FindAttribute(anAttr, "AttributeName")) { + aName = SALOMEDS::AttributeName::_narrow(anAttr); + QString newName = QString(aName->Value()); + newName = SALOMEGUI_NameDlg::getName(QAD_Application::getDesktop(), newName); + if (!newName.isEmpty()) { + smeshGUI->myActiveStudy->renameIObject(IObject, newName); + } + } + } + } + break; + } + + case 1102: // REMOVE HYPOTHESIS / ALGORITHMS + { + if(checkLock(aStudy)) break; + QAD_WaitCursor wc; + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + SALOME_ListIteratorOfListIO It(Sel->StoredIObjects()); + for (int i = 0; It.More(); It.Next(), i++) { + Handle(SALOME_InteractiveObject) IObject = It.Value(); + smeshGUI->RemoveHypothesisOrAlgorithmOnMesh(IObject); + } + Sel->ClearIObjects(); + smeshGUI->myActiveStudy->updateObjBrowser(true); + break; + } + + case 401: // GEOM::EDGE + { + if(checkLock(aStudy)) break; + if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) { + smeshGUI->EmitSignalDeactivateDialog(); + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + Sel->ClearIObjects(); + smeshGUI->myDesktop->SetSelectionMode(NodeSelection, true); + smeshGUI->ViewNodes(); + SMESHGUI_AddEdgeDlg *aDlg = new SMESHGUI_AddEdgeDlg(parent, "", Sel); + } + else { + QAD_MessageBox::warn1(QAD_Application::getDesktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + case 4021: // TRIANGLE + { + if(checkLock(aStudy)) break; + if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) { + smeshGUI->EmitSignalDeactivateDialog(); + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + Sel->ClearIObjects(); + smeshGUI->myDesktop->SetSelectionMode(NodeSelection, true); + smeshGUI->ViewNodes(); + SMESHGUI_AddFaceDlg *aDlg = new SMESHGUI_AddFaceDlg(parent, "", Sel, 3); + } + else { + QAD_MessageBox::warn1(QAD_Application::getDesktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + case 4022: // QUAD + { + if(checkLock(aStudy)) break; + if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) { + smeshGUI->EmitSignalDeactivateDialog(); + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + Sel->ClearIObjects(); + smeshGUI->myDesktop->SetSelectionMode(NodeSelection, true); + smeshGUI->ViewNodes(); + SMESHGUI_AddFaceDlg *aDlg = new SMESHGUI_AddFaceDlg(parent, "", Sel, 4); + } + else { - v3d = - ((OCCViewer_ViewFrame *) smeshGUI->myActiveStudy-> - getActiveStudyFrame()->getRightFrame()->getViewFrame())-> - getViewer(); - ic = v3d->getAISContext(); - } - else if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == - VIEW_VTK) + QAD_MessageBox::warn1(QAD_Application::getDesktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + case 4031: // TETRA + { + if(checkLock(aStudy)) break; + if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) { + smeshGUI->EmitSignalDeactivateDialog(); + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + Sel->ClearIObjects(); + smeshGUI->myDesktop->SetSelectionMode(NodeSelection, true); + smeshGUI->ViewNodes(); + SMESHGUI_AddVolumeDlg *aDlg = new SMESHGUI_AddVolumeDlg(parent, "", Sel, 4); + } + else { + QAD_MessageBox::warn1(QAD_Application::getDesktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + case 4032: // HEXA + { + if(checkLock(aStudy)) break; + if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) { + smeshGUI->EmitSignalDeactivateDialog(); + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + Sel->ClearIObjects(); + smeshGUI->myDesktop->SetSelectionMode(NodeSelection, true); + smeshGUI->ViewNodes(); + SMESHGUI_AddVolumeDlg *aDlg = new SMESHGUI_AddVolumeDlg(parent, "", Sel, 8); + } + else { + QAD_MessageBox::warn1(QAD_Application::getDesktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + + case 4041: // REMOVES NODES + { + if(checkLock(aStudy)) break; + if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) { + smeshGUI->EmitSignalDeactivateDialog(); + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + Sel->ClearIObjects(); + smeshGUI->myDesktop->SetSelectionMode(NodeSelection, true); + smeshGUI->ViewNodes(); + SMESHGUI_RemoveNodesDlg *aDlg = new SMESHGUI_RemoveNodesDlg(parent, "", Sel); + } + else { + QAD_MessageBox::warn1(QAD_Application::getDesktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + case 4042: // REMOVES ELEMENTS + { + if(checkLock(aStudy)) break; + if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) { + smeshGUI->EmitSignalDeactivateDialog(); + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + Sel->ClearIObjects(); + smeshGUI->myDesktop->SetSelectionMode(CellSelection, true); + SMESHGUI_RemoveElementsDlg *aDlg = new SMESHGUI_RemoveElementsDlg(parent, "", Sel); + } + else { - Renderer = - ((VTKViewer_ViewFrame *) smeshGUI->myActiveStudy-> - getActiveStudyFrame()->getRightFrame()->getViewFrame())-> - getRenderer(); - RenWin = Renderer->GetRenderWindow(); - } - - switch (theCommandID) - { - case 33: // DELETE - smeshGUI->OnEditDelete(); - break; - - case 113: // IMPORT - case 112: - case 111: - { - smeshGUI->Import_Document(parent, theCommandID); - break; - } - - case 122: // EXPORT MED - case 121: - case 123: - { - Export_Mesh(parent, theCommandID); - break; - } - - case 200: // SCALAR BAR - { - smeshGUI->DisplayScalarBar(false); - break; - } - case 201: - { - SMESHGUI_EditScalarBarDlg *aDlg = - new SMESHGUI_EditScalarBarDlg(parent, "", false); - aDlg->show(); - break; - } - case 202: - { - smeshGUI->DisplayScalarBar(true); - break; - } - - case 1133: // DISPLAY MODE : WireFrame, Surface, Shrink - case 1132: - case 213: - case 212: - case 211: - { - smeshGUI->SetViewMode(theCommandID); - break; - } - - case 214: // UPDATE - { - smeshGUI->Update(); - break; - } - - case 300: // ERASE - { - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == - VIEW_VTK) - { - // VTK - SALOME_ListIteratorOfListIO It(Sel->StoredIObjects()); - for (; It.More(); It.Next()) - { - Handle(SALOME_InteractiveObject) IOS = It.Value(); - if (IOS->hasEntry()) - { - Standard_Boolean res; - SMESH_Actor *ac = - smeshGUI->FindActorByEntry(IOS->getEntry(), res, true); - if (res) - smeshGUI->EraseActor(ac); - } - } - } - Sel->ClearIObjects(); - smeshGUI->myActiveStudy->updateObjBrowser(true); - } - - case 301: // DISPLAY - { - if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == - VIEW_VTK) - { - // VTK - QApplication::setOverrideCursor(Qt::waitCursor); - SALOMEDS::SObject_var fatherSF = - smeshGUI->myStudy->FindObjectID(smeshGUI->myActiveStudy-> - getActiveStudyFrame()->entry()); - - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - SALOME_ListIteratorOfListIO It(Sel->StoredIObjects()); - - for (; It.More(); It.Next()) - { - Handle(SALOME_InteractiveObject) IObject = It.Value(); - if (IObject->hasEntry()) - { - Standard_Boolean res; - SMESH_Actor *ac = - smeshGUI->FindActorByEntry(IObject->getEntry(), res, - false); - if (res) - { - smeshGUI->DisplayActor(ac, true); - smeshGUI->DisplayEdges(ac); - smeshGUI->ChangeRepresentation(ac, - ac->getDisplayMode()); - } - } - } - QApplication::restoreOverrideCursor(); - } - break; - } - - case 302: // DISPLAY ONLY - { - if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == - VIEW_VTK) - { - QApplication::setOverrideCursor(Qt::waitCursor); - vtkActorCollection *theActors = Renderer->GetActors(); - theActors->InitTraversal(); - vtkActor *ac = theActors->GetNextActor(); - while (!(ac == NULL)) - { - if (ac->IsA("SMESH_Actor")) - { - SMESH_Actor *anActor = SMESH_Actor::SafeDownCast(ac); - if (!anActor->isHighlighted()) - { - //anActor->VisibilityOff(); - //NRI- : 02/12/2002 : Fixed bugId 882 - // anActor->EdgeDevice->VisibilityOff(); - // anActor->EdgeShrinkDevice->VisibilityOff(); - anActor->SetVisibility(false); - } - } - ac = theActors->GetNextActor(); - } - - // Display selection - SALOMEDS::SObject_var fatherSF = - smeshGUI->myStudy->FindObjectID(smeshGUI->myActiveStudy-> - getActiveStudyFrame()->entry()); - - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - SALOME_ListIteratorOfListIO It(Sel->StoredIObjects()); - - for (; It.More(); It.Next()) - { - Handle(SALOME_InteractiveObject) IObject = It.Value(); - SALOMEDS::SObject_var obj = - smeshGUI->myStudy->FindObjectID(IObject->getEntry()); - - VTKViewer_RenderWindowInteractor *myRenderInter = - ((VTKViewer_ViewFrame *) smeshGUI->myActiveStudy-> - getActiveStudyFrame()->getRightFrame()->getViewFrame())-> - getRWInteractor(); - // vtkQGLRenderWindowInteractor* myRenderInter= smeshGUI->myActiveStudy->getActiveStudyFrame()->getRightFrame()->getVTKView()->getRWInteractor(); - - if (myRenderInter->isInViewer(IObject)) - { - if (IObject->hasEntry()) - { - Standard_Boolean res; - SMESH_Actor *ac = - smeshGUI->FindActorByEntry(IObject->getEntry(), res, - true); - if (res) - { - smeshGUI->DisplayActor(ac, true); - smeshGUI->DisplayEdges(ac); - smeshGUI->ChangeRepresentation(ac, - ac->getDisplayMode()); - } - } - } - } - smeshGUI->myActiveStudy->updateObjBrowser(true); - QApplication::restoreOverrideCursor(); - } - break; - } - - case 400: // NODES - { - if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == - VIEW_VTK) - { //VTK - smeshGUI->EmitSignalDeactivateDialog(); - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - Sel->ClearIObjects(); - smeshGUI->myDesktop->SetSelectionMode(1, true); - parent->menuBar()->setItemChecked(9010, false); - parent->menuBar()->setItemChecked(9011, false); - smeshGUI->ViewNodes(); - SMESHGUI_NodesDlg *aDlg = new SMESHGUI_NodesDlg(parent, "", Sel); - } - else - { - QApplication::restoreOverrideCursor(); - QAD_MessageBox::warn1(QAD_Application::getDesktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), - tr("SMESH_BUT_YES")); - } - break; - } - - case 405: // MOVE NODE - { - smeshGUI->myDesktop->SetSelectionMode(1, true); - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - SMESHGUI_MoveNodesDlg *aDlg = - new SMESHGUI_MoveNodesDlg(parent, "", Sel); - break; - } - - case 701: // COMPUTE MESH - { - if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == - VIEW_VTK) - { //VTK - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - int nbSel = Sel->IObjectCount(); - if (nbSel != 1) - { - QApplication::restoreOverrideCursor(); - break; - } - - SMESH::SMESH_Mesh_var aM; - SMESH::SMESH_subMesh_var aSubM; - Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject(); - if (IObject->hasEntry()) - { - SALOMEDS::SObject_var aMorSM = - smeshGUI->myStudy->FindObjectID(IObject->getEntry()); - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::AttributeIOR_var anIOR; - if (!aMorSM->_is_nil()) - { - if (aMorSM->FindAttribute(anAttr, "AttributeIOR")) - { - anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - MESSAGE("SMESHGUI::OnGUIEvent - Compute mesh : IOR = " - << anIOR->Value())CORBA::Object_var cobj; - try - { - cobj = _orb->string_to_object(anIOR->Value()); - if (CORBA::is_nil(cobj)) - { - MESSAGE - ("SMESHGUI::OnGUIEvent - Compute mesh : nil object")} - } - catch(CORBA::COMM_FAILURE & ex) - { - MESSAGE - ("SMESHGUI::OnGUIEvent - Compute mesh : exception (1)")} - aM = SMESH::SMESH_Mesh::_narrow(cobj); - //aM = SMESH::SMESH_Mesh::_narrow( _orb->string_to_object(anIOR->Value()) ); - aSubM = - SMESH::SMESH_subMesh::_narrow(_orb-> - string_to_object(anIOR->Value())); - if (!aM->_is_nil()) - { - GEOM::GEOM_Shape_var refShape = - smeshGUI->myStudyAPI. - GetShapeOnMeshOrSubMesh(aMorSM); - if (!refShape->_is_nil()) - { - bool compute = - smeshGUI->myComponentMesh-> - IsReadyToCompute(aM, refShape); - if (!compute) - { - QApplication::restoreOverrideCursor(); - QAD_MessageBox::warn1(QAD_Application:: - getDesktop(), tr("SMESH_WRN_WARNING"), - tr("SMESH_WRN_MISSING_PARAMETERS"), - tr("SMESH_BUT_YES")); - break; - } - try - { - smeshGUI->myComponentMesh->Compute(aM, - refShape); - smeshGUI->myStudyAPI.ModifiedMesh(aMorSM, - true); - // TO Do : change icon of all submeshes - } - catch(const SALOME::SALOME_Exception & S_ex) - { - QtCatchCorbaException(S_ex); - } - } - } - else if (!aSubM->_is_nil()) - { - aM = aSubM->GetFather(); - GEOM::GEOM_Shape_var refShape = - smeshGUI->myStudyAPI. - GetShapeOnMeshOrSubMesh(aMorSM); - if (!refShape->_is_nil()) - { - bool compute = - smeshGUI->myComponentMesh-> - IsReadyToCompute(aM, refShape); - if (!compute) - { - QApplication::restoreOverrideCursor(); - QAD_MessageBox::warn1(QAD_Application:: - getDesktop(), tr("SMESH_WRN_WARNING"), - tr("SMESH_WRN_MISSING_PARAMETERS"), - tr("SMESH_BUT_YES")); - break; - } - try - { - smeshGUI->myComponentMesh->Compute(aM, - refShape); - smeshGUI->myStudyAPI.ModifiedMesh(aMorSM, - true); - // TO Do : change icon of all submeshes - } - catch(const SALOME::SALOME_Exception & S_ex) - { - QtCatchCorbaException(S_ex); - } - } - } - } - } - } - - // Check whether the actor for the mesh exists at least in one view - Standard_Boolean res; - SMESH_Actor *ac = - smeshGUI->FindActorByEntry(IObject->getEntry(), res, false); - if (!res) - smeshGUI->InitActor(aM); - else - { - // Check whether the actor belongs to the active view - VTKViewer_RenderWindowInteractor *rwInter = - ((VTKViewer_ViewFrame *) smeshGUI->myActiveStudy-> - getActiveStudyFrame()->getRightFrame()->getViewFrame())-> - getRWInteractor(); - - // The actor belongs to inactive view -> create a copy and add it in the active view - if (!rwInter->isInViewer(IObject)) - { - SMESH_Actor *acCopy = SMESH_Actor::New(); - acCopy->ShallowCopy(ac); - - smeshGUI->DisplayActor(acCopy, false); - } - } - - if (smeshGUI->myAutomaticUpdate) - { - SMESH_Actor *Mesh = smeshGUI->ReadScript(aM); - if (Mesh != NULL) - { -#ifdef TRACE - Dump(Mesh); -#endif - smeshGUI->DisplayActor(Mesh, true); - smeshGUI->DisplayEdges(Mesh, true); - smeshGUI->ChangeRepresentation(Mesh, - Mesh->getDisplayMode()); - } - } - } - else - { - QApplication::restoreOverrideCursor(); - QAD_MessageBox::warn1(QAD_Application::getDesktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), - tr("SMESH_BUT_YES")); - } - QApplication::restoreOverrideCursor(); - break; - } - - case 702: // ADD SUB MESH - { - if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == - VIEW_VTK) - { //VTK - smeshGUI->EmitSignalDeactivateDialog(); - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - SMESHGUI_AddSubMeshDlg *aDlg = - new SMESHGUI_AddSubMeshDlg(parent, "", Sel); - } - else - { - QApplication::restoreOverrideCursor(); - QAD_MessageBox::warn1(QAD_Application::getDesktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), - tr("SMESH_BUT_YES")); - } - break; - } - - case 703: // INIT MESH - { - smeshGUI->EmitSignalDeactivateDialog(); - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - SMESHGUI_InitMeshDlg *aDlg = new SMESHGUI_InitMeshDlg(parent, "", Sel); - break; - } - - case 704: // EDIT Hypothesis - { - smeshGUI->EmitSignalDeactivateDialog(); - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - SMESHGUI_EditHypothesesDlg *aDlg = - new SMESHGUI_EditHypothesesDlg(parent, "", Sel); - break; - } - - case 705: // EDIT Global Hypothesis - { - smeshGUI->EmitSignalDeactivateDialog(); - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - SMESHGUI_EditHypothesesDlg *aDlg = - new SMESHGUI_EditHypothesesDlg(parent, "", Sel); - break; - } - - case 706: // EDIT Local Hypothesis - { - smeshGUI->EmitSignalDeactivateDialog(); - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - SMESHGUI_EditHypothesesDlg *aDlg = - new SMESHGUI_EditHypothesesDlg(parent, "", Sel); - break; - } - - case 806: // ORIENTATION ELEMENTS - { - smeshGUI->EmitSignalDeactivateDialog(); - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - smeshGUI->myDesktop->SetSelectionMode(3, true); - SMESHGUI_OrientationElementsDlg *aDlg = - new SMESHGUI_OrientationElementsDlg(parent, "", Sel); - break; - } - - case 807: // DIAGONAL INVERSION - { - smeshGUI->EmitSignalDeactivateDialog(); - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - Sel->ClearIObjects(); - smeshGUI->myDesktop->SetSelectionMode(2, true); - SMESHGUI_DiagonalInversionDlg *aDlg = - new SMESHGUI_DiagonalInversionDlg(parent, "", Sel); - break; - } - - case 900: // MESH INFOS - { - smeshGUI->EmitSignalDeactivateDialog(); - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - SMESHGUI_MeshInfosDlg *aDlg = - new SMESHGUI_MeshInfosDlg(parent, "", Sel); - break; - } - - case 1001: // AUTOMATIC UPDATE PREFERENCES - { - parent->menuBar()->setItemChecked(1001, - !parent->menuBar()->isItemChecked(1001)); - if (parent->menuBar()->isItemChecked(1001)) - { - QAD_CONFIG->addSetting("SMESH:AutomaticUpdate", "true"); - smeshGUI->myAutomaticUpdate = true; - } - else - { - QAD_CONFIG->addSetting("SMESH:AutomaticUpdate", "false"); - smeshGUI->myAutomaticUpdate = false; - } - break; - } - - case 1003: // MESH PREFERENCES - { - smeshGUI->SetDisplaySettings(); - break; - } - - case 1005: - { - QString Bold = QAD_CONFIG->getSetting("ScalarBar:Bold"); - QString Italic = QAD_CONFIG->getSetting("ScalarBar:Italic"); - QString Shadow = QAD_CONFIG->getSetting("ScalarBar:Shadow"); - QString FontFamily = QAD_CONFIG->getSetting("ScalarBar:FontFamily"); - QString Orientation = QAD_CONFIG->getSetting("ScalarBar:Orientation"); - float Width = QAD_CONFIG->getSetting("ScalarBar:Width").toFloat(); - float Height = QAD_CONFIG->getSetting("ScalarBar:Height").toFloat(); - int NumberOfLabels = - QAD_CONFIG->getSetting("ScalarBar:NumberOfLabels").toInt(); - int NumberOfColors = - QAD_CONFIG->getSetting("ScalarBar:NumberOfColors").toInt(); - - if (Width == 0) - Width = 0.17; - if (Height == 0) - Height = 0.8; - if (NumberOfLabels == 0) - NumberOfLabels = 5; - if (NumberOfColors == 0) - NumberOfColors = 64; - - SMESHGUI_Preferences_ScalarBarDlg *aDlg = - new SMESHGUI_Preferences_ScalarBarDlg(parent, "", true); - - if (Bold.compare("true") == 0) - aDlg->Bold->setChecked(true); - else - aDlg->Bold->setChecked(false); - if (Italic.compare("true") == 0) - aDlg->Italic->setChecked(true); - else - aDlg->Italic->setChecked(false); - if (Shadow.compare("true") == 0) - aDlg->Shadow->setChecked(true); - else - aDlg->Shadow->setChecked(false); - - if (Orientation.compare("Horizontal") == 0) - aDlg->RadioHoriz->setChecked(true); - else - aDlg->RadioVert->setChecked(true); - - int NbItems = aDlg->ComboBox1->count(); - int i = 0; - aDlg->ComboBox1->setCurrentItem(i); - while (i < NbItems) - { - if (FontFamily.compare(aDlg->ComboBox1->text(i)) == 0) - aDlg->ComboBox1->setCurrentItem(i); - i++; - } - - aDlg->LineEditWidth->setText(QString("%1").arg(Width)); - aDlg->LineEditHeight->setText(QString("%1").arg(Height)); - - aDlg->SpinBoxLabels->setValue(NumberOfLabels); - aDlg->SpinBoxColors->setValue(NumberOfColors); - - aDlg->show(); - if (aDlg->result()) - { - if (aDlg->RadioHoriz->isChecked()) - Orientation = "Horizontal"; - else - Orientation = "Vertical"; - if (aDlg->Bold->isChecked()) - Bold = "true"; - else - Bold = "false"; - if (aDlg->Italic->isChecked()) - Italic = "true"; - else - Italic = "false"; - if (aDlg->Shadow->isChecked()) - Shadow = "true"; - else - Shadow = "false"; - - FontFamily = aDlg->ComboBox1->currentText(); - Width = aDlg->LineEditWidth->text().toFloat(); - Height = aDlg->LineEditHeight->text().toFloat(); - NumberOfColors = aDlg->SpinBoxColors->text().toInt(); - NumberOfLabels = aDlg->SpinBoxLabels->text().toInt(); - - vtkScalarBarActor *aScalarBar = smeshGUI->GetScalarBar(); - if (aScalarBar != NULL) - { - smeshGUI->SetSettingsScalarBar(aScalarBar, Bold, Italic, Shadow, - FontFamily, Orientation, - Width, Height, NumberOfColors, NumberOfLabels); - } - - QAD_CONFIG->addSetting("ScalarBar:Bold", Bold); - QAD_CONFIG->addSetting("ScalarBar:Italic", Italic); - QAD_CONFIG->addSetting("ScalarBar:Shadow", Shadow); - QAD_CONFIG->addSetting("ScalarBar:FontFamily", FontFamily); - QAD_CONFIG->addSetting("ScalarBar:Orientation", Orientation); - QAD_CONFIG->addSetting("ScalarBar:Width", Width); - QAD_CONFIG->addSetting("ScalarBar:Height", Height); - QAD_CONFIG->addSetting("ScalarBar:NumberOfLabels", NumberOfLabels); - QAD_CONFIG->addSetting("ScalarBar:NumberOfColors", NumberOfColors); - } - break; - } - - case 1100: // EDIT HYPOTHESIS - { - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - int nbSel = Sel->IObjectCount(); - - if (nbSel == 1) - { - Standard_Boolean res; - SMESH::SMESH_Hypothesis_var Hyp = - smeshGUI->ConvertIOinSMESHHypothesis(Sel->firstIObject(), res); - - /* Look for all mesh objects that have this hupothesis affected in order to flag as ModifiedMesh */ - /* At end below '...->updateObjBrowser(true)' will change icon of mesh objects */ - /* Warning : however by internal mechanism all subMeshes icons are changed ! */ - SALOMEDS::Study::ListOfSObject_var listSOmesh = - smeshGUI->GetMeshesUsingAlgoOrHypothesis(Hyp); - - if (res) - { - QString Name = Hyp->GetName(); - - if (Name.compare("LocalLength") == 0) - { - SMESH::SMESH_LocalLength_var LL = - SMESH::SMESH_LocalLength::_narrow(Hyp); - double beforeLength = LL->GetLength(); - double Length = smeshGUI->Parameter(res, - beforeLength, - tr("SMESH_LOCAL_LENGTH_HYPOTHESIS"), - tr("SMESH_VALUE"), - 1.0E-5, 1E6, 6); - if (res && Length != beforeLength) - { - LL->SetLength(Length); - for (int i = 0; i < listSOmesh->length(); i++) - { - smeshGUI->GetStudyAPI().ModifiedMesh(listSOmesh[i], - false); - } - break; - } - - } - else if (Name.compare("NumberOfSegments") == 0) - { - SMESH::SMESH_NumberOfSegments_var NOS = - SMESH::SMESH_NumberOfSegments::_narrow(Hyp); - int beforeNbSeg = NOS->GetNumberOfSegments(); - int NbSeg = smeshGUI->Parameter(res, - beforeNbSeg, - tr("SMESH_NB_SEGMENTS_HYPOTHESIS"), - tr("SMESH_VALUE"), - 1, 1000000); - - if (res && NbSeg != beforeNbSeg) - { - NOS->SetNumberOfSegments(NbSeg); - for (int i = 0; i < listSOmesh->length(); i++) - { - SALOMEDS::SObject_var SO = listSOmesh[i]; - smeshGUI->GetStudyAPI().ModifiedMesh(listSOmesh[i], - false); - } - break; - } - - } - else if (Name.compare("MaxElementArea") == 0) - { - SMESH::SMESH_MaxElementArea_var MEA = - SMESH::SMESH_MaxElementArea::_narrow(Hyp); - double beforeMaxArea = MEA->GetMaxElementArea(); - double MaxArea = smeshGUI->Parameter(res, - beforeMaxArea, - tr("SMESH_MAX_ELEMENT_AREA_HYPOTHESIS"), - tr("SMESH_VALUE"), - 1.0E-5, 1E6, 6); - if (res && MaxArea != beforeMaxArea) - { - MEA->SetMaxElementArea(MaxArea); - for (int i = 0; i < listSOmesh->length(); i++) - { - smeshGUI->GetStudyAPI().ModifiedMesh(listSOmesh[i], - false); - } - break; - } - - } - else if (Name.compare("MaxElementVolume") == 0) - { - SMESH::SMESH_MaxElementVolume_var MEV = - SMESH::SMESH_MaxElementVolume::_narrow(Hyp); - double beforeMaxVolume = MEV->GetMaxElementVolume(); - double MaxVolume = smeshGUI->Parameter(res, - beforeMaxVolume, - tr("SMESH_MAX_ELEMENT_VOLUME_HYPOTHESIS"), - tr("SMESH_VALUE"), - 1.0E-5, 1E6, 6); - if (res && MaxVolume != beforeMaxVolume) - { - MEV->SetMaxElementVolume(MaxVolume); - for (int i = 0; i < listSOmesh->length(); i++) - { - smeshGUI->GetStudyAPI().ModifiedMesh(listSOmesh[i], - false); - } - break; - } - - } - else if (Name.compare("Regular_1D") == 0) - { - } - else if (Name.compare("MEFISTO_2D") == 0) - { - } - else - { - } - - } - } - break; - } - - case 1101: // RENAME - { - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - SALOME_ListIteratorOfListIO It(Sel->StoredIObjects()); - for (; It.More(); It.Next()) - { - Handle(SALOME_InteractiveObject) IObject = It.Value(); - - SALOMEDS::SObject_var obj = - smeshGUI->myStudy->FindObjectID(IObject->getEntry()); - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::AttributeName_var aName; - if (!obj->_is_nil()) - { - if (obj->FindAttribute(anAttr, "AttributeName")) - { - aName = SALOMEDS::AttributeName::_narrow(anAttr); - QString newName = QString(aName->Value()); - newName = - SALOMEGUI_NameDlg::getName(QAD_Application:: - getDesktop(), newName); - if (!newName.isEmpty()) - { - QApplication::setOverrideCursor(Qt::waitCursor); - smeshGUI->myActiveStudy->renameIObject(IObject, - newName); - } - QApplication::restoreOverrideCursor(); - } - } - } - break; - } - - case 1102: // REMOVE HYPOTHESIS / ALGORITHMS - { - QApplication::setOverrideCursor(Qt::waitCursor); - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - SALOME_ListIteratorOfListIO It(Sel->StoredIObjects()); - for (int i = 0; It.More(); It.Next(), i++) - { - Handle(SALOME_InteractiveObject) IObject = It.Value(); - smeshGUI->RemoveHypothesisOrAlgorithmOnMesh(IObject); - } - Sel->ClearIObjects(); - smeshGUI->myActiveStudy->updateObjBrowser(true); - QApplication::restoreOverrideCursor(); - break; - } - - case 401: // GEOM::EDGE - { - if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == - VIEW_VTK) - { //VTK - smeshGUI->EmitSignalDeactivateDialog(); - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - Sel->ClearIObjects(); - smeshGUI->myDesktop->SetSelectionMode(1, true); - parent->menuBar()->setItemChecked(9010, false); - parent->menuBar()->setItemChecked(9011, false); - smeshGUI->ViewNodes(); - SMESHGUI_AddEdgeDlg *aDlg = - new SMESHGUI_AddEdgeDlg(parent, "", Sel); - } - else - { - QApplication::restoreOverrideCursor(); - QAD_MessageBox::warn1(QAD_Application::getDesktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), - tr("SMESH_BUT_YES")); - } - break; - } - case 4021: // TRIANGLE - { - if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == - VIEW_VTK) - { //VTK - smeshGUI->EmitSignalDeactivateDialog(); - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - Sel->ClearIObjects(); - smeshGUI->myDesktop->SetSelectionMode(1, true); - parent->menuBar()->setItemChecked(9010, false); - parent->menuBar()->setItemChecked(9011, false); - smeshGUI->ViewNodes(); - SMESHGUI_AddFaceDlg *aDlg = - new SMESHGUI_AddFaceDlg(parent, "", Sel, 3); - } - else - { - QApplication::restoreOverrideCursor(); - QAD_MessageBox::warn1(QAD_Application::getDesktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), - tr("SMESH_BUT_YES")); - } - break; - } - case 4022: // QUAD - { - if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == - VIEW_VTK) - { //VTK - smeshGUI->EmitSignalDeactivateDialog(); - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - Sel->ClearIObjects(); - smeshGUI->myDesktop->SetSelectionMode(1, true); - parent->menuBar()->setItemChecked(9010, false); - parent->menuBar()->setItemChecked(9011, false); - smeshGUI->ViewNodes(); - SMESHGUI_AddFaceDlg *aDlg = - new SMESHGUI_AddFaceDlg(parent, "", Sel, 4); - } - else - { - QApplication::restoreOverrideCursor(); - QAD_MessageBox::warn1(QAD_Application::getDesktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), - tr("SMESH_BUT_YES")); - } - break; - } - case 4031: // TETRA - { - if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == - VIEW_VTK) - { //VTK - smeshGUI->EmitSignalDeactivateDialog(); - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - Sel->ClearIObjects(); - smeshGUI->myDesktop->SetSelectionMode(1, true); - parent->menuBar()->setItemChecked(9010, false); - parent->menuBar()->setItemChecked(9011, false); - smeshGUI->ViewNodes(); - SMESHGUI_AddVolumeDlg *aDlg = - new SMESHGUI_AddVolumeDlg(parent, "", Sel, 4); - } - else - { - QApplication::restoreOverrideCursor(); - QAD_MessageBox::warn1(QAD_Application::getDesktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), - tr("SMESH_BUT_YES")); - } - break; - } - case 4032: // HEXA - { - if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == - VIEW_VTK) - { //VTK - smeshGUI->EmitSignalDeactivateDialog(); - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - Sel->ClearIObjects(); - smeshGUI->myDesktop->SetSelectionMode(1, true); - parent->menuBar()->setItemChecked(9010, false); - parent->menuBar()->setItemChecked(9011, false); - smeshGUI->ViewNodes(); - SMESHGUI_AddVolumeDlg *aDlg = - new SMESHGUI_AddVolumeDlg(parent, "", Sel, 8); - } - else - { - QApplication::restoreOverrideCursor(); - QAD_MessageBox::warn1(QAD_Application::getDesktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), - tr("SMESH_BUT_YES")); - } - break; - } - - case 4041: // REMOVES NODES - { - if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == - VIEW_VTK) - { //VTK - smeshGUI->EmitSignalDeactivateDialog(); - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - Sel->ClearIObjects(); - smeshGUI->myDesktop->SetSelectionMode(1, true); - parent->menuBar()->setItemChecked(9010, false); - parent->menuBar()->setItemChecked(9011, false); - smeshGUI->ViewNodes(); - SMESHGUI_RemoveNodesDlg *aDlg = - new SMESHGUI_RemoveNodesDlg(parent, "", Sel); - } - else - { - QApplication::restoreOverrideCursor(); - QAD_MessageBox::warn1(QAD_Application::getDesktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), - tr("SMESH_BUT_YES")); - } - break; - } - case 4042: // REMOVES ELEMENTS - { - if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == - VIEW_VTK) - { //VTK - smeshGUI->EmitSignalDeactivateDialog(); - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - Sel->ClearIObjects(); - smeshGUI->myDesktop->SetSelectionMode(3, true); - SMESHGUI_RemoveElementsDlg *aDlg = - new SMESHGUI_RemoveElementsDlg(parent, "", Sel); - } - else - { - QApplication::restoreOverrideCursor(); - QAD_MessageBox::warn1(QAD_Application::getDesktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), - tr("SMESH_BUT_YES")); - } - break; - } - - case 5000: // HYPOTHESIS - ALGO - { - smeshGUI->CreateAlgorithm("Regular_1D", "Wire Discretisation"); - break; - } - case 5010: - { - smeshGUI->CreateAlgorithm("MEFISTO_2D", "Triangle (Mefisto)"); - break; - } - case 5011: - { - smeshGUI->CreateAlgorithm("Quadrangle_2D", "Quadrangle (Mapping)"); - break; - } - case 5020: - { - smeshGUI->CreateAlgorithm("Hexa_3D", "Hexahedron (i,j,k)"); - break; - } - case 5021: - { - smeshGUI->CreateAlgorithm("NETGEN_3D", "Tetrahedron (Netgen)"); - break; - } - - case 5030: // HYPOTHESIS - LOCAL LENGTH - { - smeshGUI->EmitSignalDeactivateDialog(); - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - SMESHGUI_LocalLengthDlg *aDlg = new SMESHGUI_LocalLengthDlg(parent, ""); - break; - } - case 5031: // HYPOTHESIS - NB SEGMENTS - { - smeshGUI->EmitSignalDeactivateDialog(); - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - SMESHGUI_NbSegmentsDlg *aDlg = new SMESHGUI_NbSegmentsDlg(parent, ""); - break; - } - - case 5032: // HYPOTHESIS - MAX ELEMENT AREA - { - smeshGUI->EmitSignalDeactivateDialog(); - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - SMESHGUI_MaxElementAreaDlg *aDlg = - new SMESHGUI_MaxElementAreaDlg(parent, ""); - break; - } - - case 5033: // HYPOTHESIS - MAX ELEMENT VOLUME - { - smeshGUI->EmitSignalDeactivateDialog(); - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - SMESHGUI_MaxElementVolumeDlg *aDlg = - new SMESHGUI_MaxElementVolumeDlg(parent, ""); - break; - } - - case 5034: // HYPOTHESIS - LENGTH FROM EDGES - { - SMESH::SMESH_Hypothesis_var Hyp; - try - { - Hyp = smeshGUI->myComponentMesh->CreateHypothesis("LengthFromEdges", smeshGUI->myStudyId); - - if (!Hyp->_is_nil()) - { - SALOMEDS::SObject_var SHyp = smeshGUI->myStudyAPI.AddNewHypothesis(Hyp); - smeshGUI->myStudyAPI.SetName(SHyp, "LengthFromEdges"); - } - } - catch(const SALOME::SALOME_Exception & S_ex) - { - QtCatchCorbaException(S_ex); - } - smeshGUI->myActiveStudy->updateObjBrowser(true); - - break; - } - - case 6016: // CONTROLS - case 6015: - case 6014: - case 6013: - case 6012: - case 6011: - case 6001: - { - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - int nbSel = Sel->IObjectCount(); - if (nbSel != 1) - break; - smeshGUI->Control(theCommandID); - break; - } - - case 6002: - { - if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == - VIEW_VTK) - { //VTK - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - SMESHGUI_EdgesConnectivityDlg *Dlg = - new SMESHGUI_EdgesConnectivityDlg(parent, "", Sel); - } - else - { - QApplication::restoreOverrideCursor(); - QAD_MessageBox::warn1(QAD_Application::getDesktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), - tr("SMESH_BUT_YES")); - } - break; - } - - case 9010: - { - if (!parent->menuBar()->isItemChecked(9010)) - { - QApplication::setOverrideCursor(Qt::waitCursor); - parent->menuBar()->setItemChecked(9011, false); - - smeshGUI->EraseSimulationActors(); - smeshGUI->mySimulationActors2D = vtkActor2DCollection::New(); - - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - int nbSel = Sel->IObjectCount(); - if (nbSel == 1) - { - Standard_Boolean res; - SMESH_Actor *MeshActor = - smeshGUI->FindActorByEntry(Sel->firstIObject()->getEntry(), - res, true); - if (res) - { - parent->menuBar()->setItemChecked(9010, - !parent->menuBar()->isItemChecked(9010)); - - // It's necessary to display SMDS IDs instead of VTK ones, so - // vtkIdFilter is unacceptable here. We have to do it manually :( - vtkUnstructuredGrid *ptGrid = vtkUnstructuredGrid::New(); - ptGrid->CopyStructure(MeshActor->DataSource); - - int numPts = MeshActor->DataSource->GetNumberOfPoints(); - - // Loop over points and generate ids - vtkIntArray *ptIds = vtkIntArray::New(); - ptIds->SetNumberOfValues(numPts); - - for (int id = 0; id < numPts; id++) - { - int idSMDS = MeshActor->GetIdSMESHDSNode(id); - ptIds->SetValue(id, idSMDS); - } - -// mpv porting vtk4.2.2 - // vtkScalars* newScalars = vtkScalars::New(); - // newScalars->SetData(ptIds); - // ptGrid->GetPointData()->SetScalars(newScalars); - ptGrid->GetPointData()->SetScalars(ptIds); - // newScalars->Delete(); -// mpv - ptIds->Delete(); - - vtkMaskPoints *mask = vtkMaskPoints::New(); - mask->SetInput(ptGrid); - mask->SetOnRatio(1); - // mask->SetMaximumNumberOfPoints( 50 ); - // mask->RandomModeOn(); - - vtkSelectVisiblePoints *visPts = - vtkSelectVisiblePoints::New(); - visPts->SetInput(mask->GetOutput()); - visPts->SetRenderer(((VTKViewer_ViewFrame *) smeshGUI-> - myActiveStudy->getActiveStudyFrame()-> - getRightFrame()->getViewFrame())->getRenderer()); - //visPts->SetSelectInvisible(1); - visPts->SelectInvisibleOff(); - visPts->SetTolerance(0.1); - - vtkLabeledDataMapper *ldm = vtkLabeledDataMapper::New(); - ldm->SetInput(visPts->GetOutput()); - ldm->SetLabelFormat("%g"); - ldm->SetLabelModeToLabelScalars(); - //ldm->SetLabelModeToLabelFieldData(); - - ldm->SetFontFamilyToTimes(); - ldm->SetFontSize(6 * parent->font().pointSize() / 5); - ldm->SetBold(1); - ldm->SetItalic(0); - ldm->SetShadow(0); - - vtkActor2D *pointLabels = vtkActor2D::New(); - pointLabels->SetMapper(ldm); - pointLabels->GetProperty()->SetColor(0, 1, 0); - - visPts->Delete(); - ldm->Delete(); - smeshGUI->mySimulationActors2D->AddItem(pointLabels); - ((VTKViewer_ViewFrame *) smeshGUI->myActiveStudy-> - getActiveStudyFrame()->getRightFrame()-> - getViewFrame())->getRenderer()->AddActor2D(pointLabels); - } - } - } - else - { - QApplication::setOverrideCursor(Qt::waitCursor); - parent->menuBar()->setItemChecked(9010, - !parent->menuBar()->isItemChecked(9010)); - smeshGUI->EraseSimulationActors(); - smeshGUI->ScalarVisibilityOff(); - } - QApplication::restoreOverrideCursor(); - break; - } - case 9011: - { - if (!parent->menuBar()->isItemChecked(9011)) - { - QApplication::setOverrideCursor(Qt::waitCursor); - parent->menuBar()->setItemChecked(9010, false); - - smeshGUI->EraseSimulationActors(); - smeshGUI->mySimulationActors2D = vtkActor2DCollection::New(); - - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - int nbSel = Sel->IObjectCount(); - if (nbSel == 1) - { - Standard_Boolean res; - SMESH_Actor *MeshActor = - smeshGUI->FindActorByEntry(Sel->firstIObject()->getEntry(), - res, true); - if (res) - { - parent->menuBar()->setItemChecked(9011, - !parent->menuBar()->isItemChecked(9011)); - - // It's necessary to display SMDS IDs instead of VTK ones, so - // vtkIdFilter is unacceptable here. We have to do it manually :( - vtkUnstructuredGrid *elGrid = vtkUnstructuredGrid::New(); - elGrid->CopyStructure(MeshActor->DataSource); - - int numCells = MeshActor->DataSource->GetNumberOfCells(); - - // Loop over points and generate ids - vtkIntArray *cellIds = vtkIntArray::New(); - cellIds->SetNumberOfValues(numCells); - - for (int id = 0; id < numCells; id++) - { - int idSMDS = MeshActor->GetIdSMESHDSElement(id); - cellIds->SetValue(id, idSMDS); - } - -// mpv porting vk4.2.2 - // vtkScalars* newScalars = vtkScalars::New(); - // newScalars->SetData(cellIds); - elGrid->GetCellData()->SetScalars(cellIds); - // elGrid->GetCellData()->SetScalars(newScalars); - // newScalars->Delete(); -//mpv - - cellIds->Delete(); - - vtkCellCenters *cc = vtkCellCenters::New(); - cc->SetInput(elGrid); - - vtkSelectVisiblePoints *visCells = - vtkSelectVisiblePoints::New(); - visCells->SetInput(cc->GetOutput()); - visCells->SetRenderer(((VTKViewer_ViewFrame *) smeshGUI-> - myActiveStudy->getActiveStudyFrame()-> - getRightFrame()->getViewFrame())->getRenderer()); - visCells->SelectInvisibleOff(); - visCells->SetTolerance(0.1); - // visCells->SetSelectInvisible(1); - - vtkLabeledDataMapper *ldm = vtkLabeledDataMapper::New(); - ldm->SetInput(visCells->GetOutput()); - ldm->SetLabelFormat("%g"); - ldm->SetLabelModeToLabelScalars(); - - ldm->SetFontFamilyToTimes(); - ldm->SetFontSize(6 * parent->font().pointSize() / 5); - ldm->SetBold(1); - ldm->SetItalic(0); - ldm->SetShadow(0); - - vtkActor2D *cellLabels = vtkActor2D::New(); - cellLabels->SetMapper(ldm); - cellLabels->GetProperty()->SetColor(1, 0, 0); - - cc->Delete(); - visCells->Delete(); - ldm->Delete(); - smeshGUI->mySimulationActors2D->AddItem(cellLabels); - ((VTKViewer_ViewFrame *) smeshGUI->myActiveStudy-> - getActiveStudyFrame()->getRightFrame()-> - getViewFrame())->getRenderer()->AddActor2D(cellLabels); - } - } - } - else - { - QApplication::setOverrideCursor(Qt::waitCursor); - parent->menuBar()->setItemChecked(9011, - !parent->menuBar()->isItemChecked(9011)); - smeshGUI->EraseSimulationActors(); - smeshGUI->ScalarVisibilityOff(); - } - QApplication::restoreOverrideCursor(); - break; - } - - case 10001: // DISPLAY MODE PREFERENCE - { - parent->menuBar()->setItemChecked(10001, - !parent->menuBar()->isItemChecked(10001)); - parent->menuBar()->setItemChecked(10002, false); - parent->menuBar()->setItemChecked(10003, false); - QAD_CONFIG->addSetting("SMESH:DisplayMode", "Wireframe"); - break; - } - case 10002: - { - parent->menuBar()->setItemChecked(10002, - !parent->menuBar()->isItemChecked(10002)); - parent->menuBar()->setItemChecked(10001, false); - parent->menuBar()->setItemChecked(10003, false); - QAD_CONFIG->addSetting("SMESH:DisplayMode", "Shading"); - break; - } - case 10003: - { - parent->menuBar()->setItemChecked(10003, - !parent->menuBar()->isItemChecked(10003)); - parent->menuBar()->setItemChecked(10002, false); - parent->menuBar()->setItemChecked(10001, false); - QAD_CONFIG->addSetting("SMESH:DisplayMode", "Shrink"); - break; - } - - } - - smeshGUI->myActiveStudy->updateObjBrowser(true); - return true; -} - -//============================================================================= -/*! function : GetMeshesUsingAlgoOrHypothesis() - * purpose : return a list of Study objects (mesh kind) that have 'AlgoOrHyp' affected. - * : However is supposed here that father of father of an hypothesis is a Mesh Object. - */ -//============================================================================= -SALOMEDS::Study::ListOfSObject * - SMESHGUI::GetMeshesUsingAlgoOrHypothesis(SMESH:: - SMESH_Hypothesis_ptr AlgoOrHyp) -{ - SALOMEDS::Study::ListOfSObject_var listSOmesh = - new SALOMEDS::Study::ListOfSObject; - listSOmesh->length(0); - unsigned int index = 0; - if (!AlgoOrHyp->_is_nil()) - { - SALOMEDS::SObject_var SO_Hypothesis = - smeshGUI->GetStudyAPI().FindHypothesisOrAlgorithms(AlgoOrHyp); - if (!SO_Hypothesis->_is_nil()) - { - SALOMEDS::Study::ListOfSObject_var listSO = - smeshGUI->myStudy->FindDependances(SO_Hypothesis); - for (unsigned int i = 0; i < listSO->length(); i++) - { - SALOMEDS::SObject_var SO = listSO[i]; - if (!SO->_is_nil()) - { - SALOMEDS::SObject_var SOfatherFather = - SO->GetFather()->GetFather(); - if (!SOfatherFather->_is_nil()) - { - index++; - listSOmesh->length(index); - listSOmesh[index - 1] = SOfatherFather; - } - } - } - } - } - return listSOmesh._retn(); -} - -//============================================================================= -/*! - * - */ -//============================================================================= -void SMESHGUI::Export_Mesh(QAD_Desktop * parent, int theCommandID) -{ - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); - int nbSel = Sel->IObjectCount(); - if (nbSel == 1) - { - Standard_Boolean res; - Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject(); - SMESH::SMESH_Mesh_var aMesh = smeshGUI->ConvertIOinMesh(IObject, res); - if (res) - { - QString filename; - if (theCommandID == 122) - { // EXPORT MED - QString filename = QAD_FileDlg::getFileName(parent, - "", - tr("MED files (*.med)"), - tr("Export mesh"), - false); - if (!filename.isEmpty()) - { - QApplication::setOverrideCursor(Qt::waitCursor); - aMesh->Export(filename.latin1(), "MED"); - QApplication::restoreOverrideCursor(); - } - } - else if (theCommandID == 121) - { // EXPORT DAT - QString filename = QAD_FileDlg::getFileName(parent, - "", - tr("DAT files (*.dat)"), - tr("Export mesh"), - false); - if (!filename.isEmpty()) - { - QApplication::setOverrideCursor(Qt::waitCursor); - aMesh->Export(filename.latin1(), "DAT"); - QApplication::restoreOverrideCursor(); - } - } - else if (theCommandID == 123) - { // EXPORT UNV - QString filename = QAD_FileDlg::getFileName(parent, - "", - tr("IDEAS files (*.unv)"), - tr("Export mesh"), - false); - if (!filename.isEmpty()) - { - QApplication::setOverrideCursor(Qt::waitCursor); - aMesh->Export(filename.latin1(), "UNV"); - QApplication::restoreOverrideCursor(); - } - } - else - aMesh->Export(filename.latin1(), "DAT"); - - if (IObject->hasEntry()) - { - MESSAGE("---"); - SALOMEDS::SObject_var SO = - smeshGUI->myStudy->FindObjectID(IObject->getEntry()); - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::AttributeComment_var aFileName; - - SALOMEDS::StudyBuilder_var aStudyBuilder = - smeshGUI->myStudy->NewBuilder(); - - anAttr = - aStudyBuilder->FindOrCreateAttribute(SO, "AttributeComment"); - aFileName = SALOMEDS::AttributeComment::_narrow(anAttr); - aFileName->SetValue(filename.latin1()); - - // Add a MEDFILE attribute to make selection in Efficas - if (theCommandID == 122) - { // EXPORT MED - QString medfilename="FICHIERMED"+filename; - anAttr = aStudyBuilder->FindOrCreateAttribute(SO, "AttributeComment"); - SALOMEDS::AttributeComment_var MEDFileName; - MEDFileName = SALOMEDS::AttributeComment::_narrow(anAttr); - MEDFileName->SetValue(medfilename.latin1()); - } // EXPORT MED - } - - QApplication::restoreOverrideCursor(); - } - } -} - -//============================================================================= -/*! - * - */ -//============================================================================= -void SMESHGUI::Import_Document(QAD_Desktop * parent, int theCommandID) -{ - QString filter; - string myExtension; - - if (theCommandID == 113) - { - filter = tr("MED files (*.med)"); - myExtension = string("MED"); - } - else if (theCommandID == 112) - { - filter = tr("IDEAS files (*.unv)"); - myExtension = string("UNV"); - } - else if (theCommandID == 111) - { - filter = tr("DAT files (*.dat)"); - myExtension = string("DAT"); - } - - QString filename = QAD_FileDlg::getFileName(parent, "", filter, - tr("Import document"), true); - - if (!filename.isEmpty()) - { - QApplication::setOverrideCursor(Qt::waitCursor); - try - { - if (!myComponentMesh->_is_nil()) - { - SMESH::SMESH_Mesh_var aMesh = - myComponentMesh->Import(myStudyId, filename.latin1(), - myExtension.c_str()); - - if (!aMesh->_is_nil()) - { - SALOMEDS::SObject_var SM = myStudyAPI.AddNewMesh(aMesh); - myStudyAPI.SetName(SM, filename); - } - } - } - catch(const SALOME::SALOME_Exception & S_ex) - { - QtCatchCorbaException(S_ex); - } - myActiveStudy->updateObjBrowser(true); - QApplication::restoreOverrideCursor(); - } -} - -//============================================================================= -/*! - * - */ -//============================================================================= -bool SMESHGUI::OnMousePress(QMouseEvent * pe, QAD_Desktop * parent, - QAD_StudyFrame * studyFrame) -{ - SMESHGUI::GetOrCreateSMESHGUI(parent); - return false; -} - -//============================================================================= -/*! - * - */ -//============================================================================= -bool SMESHGUI::OnMouseMove(QMouseEvent * pe, QAD_Desktop * parent, - QAD_StudyFrame * studyFrame) -{ - SMESHGUI::GetOrCreateSMESHGUI(parent); - - return true; -} - -//============================================================================= -/*! - * - */ -//============================================================================= -bool SMESHGUI::OnKeyPress(QKeyEvent * pe, QAD_Desktop * parent, - QAD_StudyFrame * studyFrame) -{ - SMESHGUI::GetOrCreateSMESHGUI(parent); - - return true; -} - -//============================================================================= -/*! - * - */ -//============================================================================= -bool SMESHGUI::SetSettings(QAD_Desktop * parent) -{ - SMESHGUI::GetOrCreateSMESHGUI(parent); - - /* Display mode */ - QString DisplayMode = QAD_CONFIG->getSetting("SMESH:DisplayMode"); - if (DisplayMode.compare("") == 0) - { - DisplayMode = "Shading"; - QAD_CONFIG->addSetting("SMESH:DisplayMode", "Shading"); - } - - if (DisplayMode.compare("Wireframe") == 0) - { - parent->menuBar()->setItemChecked(10003, false); - parent->menuBar()->setItemChecked(10002, false); - parent->menuBar()->setItemChecked(10001, true); - } - else if (DisplayMode.compare("Shading") == 0) - { - parent->menuBar()->setItemChecked(10003, false); - parent->menuBar()->setItemChecked(10002, true); - parent->menuBar()->setItemChecked(10001, false); - } - else if (DisplayMode.compare("Shrink") == 0) - { - parent->menuBar()->setItemChecked(10003, true); - parent->menuBar()->setItemChecked(10002, false); - parent->menuBar()->setItemChecked(10001, false); - } - - /* Automatic Update */ - QString AutoUpdate = QAD_CONFIG->getSetting("SMESH:AutomaticUpdate"); - if (AutoUpdate.compare("true") == 0) - { - parent->menuBar()->setItemChecked(1001, true); - smeshGUI->myAutomaticUpdate = true; - } - else - { - parent->menuBar()->setItemChecked(1001, false); - smeshGUI->myAutomaticUpdate = false; - } - - return true; -} - -//============================================================================= -/*! - * - */ -//============================================================================= -void SMESHGUI::DefinePopup(QString & theContext, QString & theParent, - QString & theObject) -{ - /* Create or retrieve an object SMESHGUI */ - SMESHGUI::GetOrCreateSMESHGUI(QAD_Application::getDesktop()); - - // NRI : Temporary added - // if ( smeshGUI->myStudy->GetProperties()->IsLocked() ) { - // theObject = "NothingSelected"; - // theContext = "NothingSelected"; - // } - // NRI - - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); - int nbSel = Sel->IObjectCount(); - if (nbSel == 0) - { - if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == - VIEW_VTK) - { - vtkScalarBarActor *aScalarBar = smeshGUI->GetScalarBar(); - if ((aScalarBar != NULL) && (aScalarBar->GetVisibility() == 1)) - { - theObject = "ScalarBar"; - theContext = ""; - } - else - { - theObject = "NothingSelected"; - theContext = "NothingSelected"; - } - } - else - { - theObject = "NothingSelected"; - theContext = "NothingSelected"; - } - } - else if (nbSel == 1) - { - theObject = smeshGUI->CheckTypeObject(Sel->firstIObject()); - theContext = ""; - } - else - { - theObject = smeshGUI->CheckHomogeneousSelection(); - theContext = ""; - } -} - -//============================================================================= -/*! - * - */ -//============================================================================= -bool SMESHGUI::CustomPopup(QAD_Desktop * parent, - QPopupMenu * popup, - const QString & theContext, - const QString & theParent, const QString & theObject) -{ - // Popup should be customized for any viewer since some meaningless commands may be present in the popup - //if (smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() != VIEW_VTK) //Test du type de viewer true=OCC false=VTK - // return false; - /* Create or retrieve an object SMESHGUI */ - SMESHGUI::GetOrCreateSMESHGUI(parent); - - // NRI : Temporary added - // if ( smeshGUI->myStudy->GetProperties()->IsLocked() ) { - // return false; - // } - // NRI - - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); - QAD_StudyFrame *studyFrame = smeshGUI->myActiveStudy->getActiveStudyFrame(); - int nbSel = Sel->IObjectCount(); - - if (nbSel == 0) - { - if (studyFrame->getTypeView() != VIEW_VTK) - popup->clear(); - return false; - } - else if (nbSel == 1) - { - QString parentComp = - ((SALOMEGUI_Desktop *) parent)->getComponentFromSelection(); - // First check type of active viewer (VTK required) - if ( /*studyFrame->getTypeView() != VIEW_VTK || */ parentComp != - parent->getActiveComponent()) - { - //MESSAGE("CustomPopup(): VTK viewer required, removing all SMESH-specific popup menu items") - while (1) - { - int id = popup->idAt(0); - if (id <= QAD_TopLabel_Popup_ID) - popup->removeItemAt(0); - else - break; - } - if (theObject.compare("Component") == 0) - { - popup->removeItem(QAD_DisplayOnly_Popup_ID); - } - return false; - } - - // Remove common popup items for Submesh, Hypothesis and Algorithm - if (theObject.compare("SubMesh") == 0 || - theObject.compare("Hypothesis") == 0 || - theObject.compare("Algorithm") == 0) - { - popup->removeItem(QAD_Display_Popup_ID); - popup->removeItem(QAD_DisplayOnly_Popup_ID); - popup->removeItem(QAD_Erase_Popup_ID); - int id = popup->idAt(popup->count() - 1); // last item - if (id < 0 && id != -1) - popup->removeItem(id); // separator - } - - if (theObject.compare("Component") == 0) - { - popup->removeItem(QAD_DisplayOnly_Popup_ID); - return true; - } - - int id = QAD_TopLabel_Popup_ID; //popup->idAt(0); - QFont f = QApplication::font(); - f.setBold(TRUE); - - Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject(); - - if (theParent.compare("Viewer") == 0) - { - if (popup->idAt(0) == id) - { - popup->removeItem(id); - popup->insertItem(new CustomItem(QString(IObject->getName()), - f), id, 0); - } - - Standard_Boolean res; - SMESH_Actor *ac = - smeshGUI->FindActorByEntry(IObject->getEntry(), res, false); - if (res && studyFrame->getTypeView() == VIEW_VTK) - { - VTKViewer_RenderWindowInteractor *myRenderInter = - ((VTKViewer_ViewFrame *) studyFrame->getRightFrame()-> - getViewFrame())->getRWInteractor(); - if (myRenderInter->isVisible(IObject)) - { - popup->removeItem(QAD_Display_Popup_ID); - } - else - { - popup->removeItem(QAD_Erase_Popup_ID); - } - } - else - { - popup->removeItem(QAD_Erase_Popup_ID); - if (!res) - { // mesh not computed -> can't display it - popup->removeItem(QAD_Display_Popup_ID); - popup->removeItem(QAD_DisplayOnly_Popup_ID); - popup->removeItemAt(popup->count() - 1); //separator - } - } - } - else if (theParent.compare("ObjectBrowser") == 0) - { - if (theObject.compare("Mesh") == 0 || - theObject.compare("SubMesh") == 0 || - theObject.compare("Hypothesis") == 0 || - theObject.compare("Algorithm") == 0) - { - popup->removeItemAt(0); - } - else - { - if (popup->idAt(0) == id) - { - popup->removeItem(id); - popup->removeItemAt(0); //separator - } - } - - Standard_Boolean res; - SMESH_Actor *ac = - smeshGUI->FindActorByEntry(IObject->getEntry(), res, false); - if (res && studyFrame->getTypeView() == VIEW_VTK) - { - VTKViewer_RenderWindowInteractor *myRenderInter = - ((VTKViewer_ViewFrame *) studyFrame->getRightFrame()-> - getViewFrame())->getRWInteractor(); - if (myRenderInter->isVisible(IObject)) - { - popup->removeItem(QAD_Display_Popup_ID); - } - else - { - popup->removeItem(QAD_Erase_Popup_ID); - } - } - else - { - if (theObject.compare("Mesh") == 0 || - theObject.compare("SubMesh") == 0 || - theObject.compare("Hypothesis") == 0 || - theObject.compare("Algorithm") == 0) - { - } - else - { - popup->removeItem(QAD_Erase_Popup_ID); - if (!res) - { // mesh not computed -> can't display it - popup->removeItem(QAD_Display_Popup_ID); - popup->removeItem(QAD_DisplayOnly_Popup_ID); - popup->removeItemAt(popup->count() - 1); //separator - } - } - } - } - } - else - { - QString parentComp = - ((SALOMEGUI_Desktop *) parent)->getComponentFromSelection(); - QAD_StudyFrame *studyFrame = - smeshGUI->myActiveStudy->getActiveStudyFrame(); - if ( /*studyFrame->getTypeView() != VIEW_VTK || */ parentComp != - parent->getActiveComponent()) - { - //MESSAGE("CustomPopup(): VTK viewer required, removing all SMESH-specific popup menu items") - while (1) - { - int id = popup->idAt(0); - if (id <= QAD_TopLabel_Popup_ID && id != -1) - popup->removeItemAt(0); - else - break; - } - if (parentComp.isNull()) - { // objects from several components are selected - popup->removeItem(QAD_DisplayOnly_Popup_ID); - popup->removeItem(QAD_Display_Popup_ID); - popup->removeItem(QAD_Erase_Popup_ID); - int id = popup->idAt(popup->count() - 1); // last item - if (id < 0 && id != -1) - popup->removeItem(id); // separator - } - return false; - } - - QString type = smeshGUI->CheckHomogeneousSelection(); - if (type.compare("Heterogeneous Selection") != 0) - { - int id = QAD_TopLabel_Popup_ID; //popup->idAt(0); - QFont f = QApplication::font(); - f.setBold(TRUE); - popup->removeItem(id); - popup->insertItem(new CustomItem(QString("%1 ").arg(nbSel) + type + - " (s) ", f), id, 0); - } - } - return false; -} - -/** - * Ensures that the actor for the given exists in the active VTK view - * @TODO Handle multiple selection. - */ -void SMESHGUI::BuildPresentation(const Handle(SALOME_InteractiveObject) & theIO) -{ - MESSAGE("SMESHGUI::BuildPresentation("<getEntry()<<")"); - /* Create or retrieve an object SMESHGUI */ - SMESHGUI::GetOrCreateSMESHGUI(QAD_Application::getDesktop()); - - QAD_StudyFrame *activeFrame = - smeshGUI->myActiveStudy->getActiveStudyFrame(); - if (activeFrame->getTypeView() == VIEW_VTK) - { - // VTK - // Some ideas to handle multiple selection... - /*SALOMEDS::SObject_var fatherSF = - smeshGUI->myStudy->FindObjectID(activeFrame->entry()); - - SALOME_Selection *Sel = - SALOME_Selection::Selection(smeshGUI->myActiveStudy-> - getSelection()); - SALOME_ListIteratorOfListIO It(Sel->StoredIObjects()); - - for(;It.More();It.Next()) { - Handle(SALOME_InteractiveObject) IObject = It.Value();*/ - Handle(SALOME_InteractiveObject) IObject = theIO; - if (IObject->hasEntry()) - { - // Look for the actor in all views - Standard_Boolean res; - SMESH_Actor *ac = - smeshGUI->FindActorByEntry(IObject->getEntry(), res, false); - - if (!res) - { - SALOMEDS::SObject_var aMorSM=smeshGUI->myStudy->FindObjectID( IObject->getEntry()); - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::AttributeIOR_var anIOR; - if(aMorSM->FindAttribute(anAttr, "AttributeIOR")) - { - anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - SMESH::SMESH_Mesh_var aM = - SMESH::SMESH_Mesh::_narrow( _orb->string_to_object(anIOR->Value())); - if(!aM->_is_nil()) - { - smeshGUI->InitActor(aM); - ac = smeshGUI->ReadScript(aM); - smeshGUI->DisplayActor( ac, true ); - smeshGUI->DisplayEdges( ac ); - smeshGUI->ChangeRepresentation( ac, ac->getDisplayMode() ); - } - else - { - MESSAGE("Do not know how to display something which is not a SMESH_Mesh"); - } - } - else - { - MESSAGE("The object "<getEntry()<< - " do not have \"AttributeIOR\" attribute"); - } - } - else - { - // The actor exists in some view - // Check whether the actor belongs to the active view - VTKViewer_RenderWindowInteractor *rwInter = - ((VTKViewer_ViewFrame *) activeFrame->getRightFrame()-> - getViewFrame())->getRWInteractor(); - - // The actor belongs to inactive view -> create a copy and display it in the active view - if (!rwInter->isInViewer(IObject)) - { - if(ac->GetMapper()==NULL) - { - SMESH::SMESH_Mesh_var aMesh = smeshGUI->ConvertIOinMesh(theIO, res); - ac=smeshGUI->ReadScript(aMesh); - } - SMESH_Actor *acCopy = SMESH_Actor::New(); - acCopy->ShallowCopy(ac); - ac = acCopy; - } - smeshGUI->DisplayActor(ac, false); - smeshGUI->DisplayEdges(ac); - smeshGUI->ChangeRepresentation(ac, ac->getDisplayMode()); - } - } - } - else - { - MESSAGE("BuildPresentation() must not be called while non-VTK view is active"); - } -} - -//============================================================================= -/*! - * - */ -//============================================================================= -void SMESHGUI::setOrb() -{ - try - { - ORB_INIT & init = *SINGLETON_ < ORB_INIT >::Instance(); - ASSERT(SINGLETON_ < ORB_INIT >::IsAlreadyExisting()); - _orb = init(0, 0); - } catch(...) - { - INFOS("internal error : orb not found"); - _orb = 0; - } - ASSERT(!CORBA::is_nil(_orb)); -} - -/** - * Get the history of all commands made in the SMESH server. This list of command - * is used to display the mesh in the VTK view - * @TODO Handle the REMOVE_ALL command. - */ -SMESH_Actor *SMESHGUI::ReadScript(SMESH::SMESH_Mesh_ptr aMesh) -{ - MESSAGE("SMESHGUI::ReadScript"); - SMESH_Actor *MeshActor; - if (!aMesh->_is_nil()) - { - Standard_Boolean result; - MeshActor = FindActor(aMesh, result, false); - if (result) - { - SMESH::log_array_var aSeq = aMesh->GetLog(true); - MESSAGE("SMESHGUI::ReadScript: The log contains "<length() - <<" commands."); - - for (unsigned int ind = 0; ind < aSeq->length(); ind++) - { - switch (aSeq[ind].commandType) - { - case SMESH::ADD_NODE: - { - AddNodes(MeshActor, aSeq[ind].number, aSeq[ind].coords, - aSeq[ind].indexes); - break; - } - case SMESH::ADD_EDGE: - { - AddEdges( MeshActor, aSeq[ind].number, aSeq[ind].coords, aSeq[ind].indexes ); - break; - } - case SMESH::ADD_TRIANGLE: - { - AddTriangles(MeshActor, aSeq[ind].number, aSeq[ind].coords, - aSeq[ind].indexes); - break; - } - case SMESH::ADD_QUADRANGLE: - { - AddQuadrangles(MeshActor, aSeq[ind].number, - aSeq[ind].coords, aSeq[ind].indexes); - break; - } - case SMESH::ADD_TETRAHEDRON: - { - AddTetras(MeshActor, aSeq[ind].number, aSeq[ind].coords, - aSeq[ind].indexes); - break; - } - case SMESH::ADD_PYRAMID: - { - break; - } - case SMESH::ADD_PRISM: - { - break; - } - case SMESH::ADD_HEXAHEDRON: - { - AddHexaedres(MeshActor, aSeq[ind].number, aSeq[ind].coords, - aSeq[ind].indexes); - break; - } - case SMESH::REMOVE_NODE: - { - RemoveNodes(MeshActor, aSeq[ind].number, aSeq[ind].coords, - aSeq[ind].indexes); - break; - } - case SMESH::REMOVE_ELEMENT: - { - RemoveElements(MeshActor, aSeq[ind].number, - aSeq[ind].coords, aSeq[ind].indexes); - break; - } - case SMESH::REMOVE_ALL: - MESSAGE("REMOVE_ALL command not yet implemented"); - break; - default: MESSAGE("Warning: Unknown script command."); - } - } - return MeshActor; - } - } - return NULL; -} - -//============================================================================= -/*! - * - */ -//============================================================================= -void SMESHGUI::Dump(SMESH_Actor * Mactor) -{ - vtkUnstructuredGrid *ugrid = - vtkUnstructuredGrid::SafeDownCast(Mactor->DataSource); - vtkPoints *Pts = ugrid->GetPoints(); - int nbPts = Pts->GetNumberOfPoints(); - int nbCells = ugrid->GetNumberOfCells(); - - FILE *In; - int i, j; - In = fopen("/tmp/dumpMesh", "w+"); - fprintf(In, "%d %d\n", nbPts, nbCells); - for (int i = 0; i < nbPts; i++) - { - float *p = ugrid->GetPoint(i); - fprintf(In, "%d %e %e %e\n", i, p[0], p[1], p[2]); - } - - for (int i = 0; i < nbCells; i++) - { - fprintf(In, "%d %d", i, ugrid->GetCell(i)->GetCellType()); - vtkIdList *Id = ugrid->GetCell(i)->GetPointIds(); - for (j = 0; j < Id->GetNumberOfIds(); j++) - { - fprintf(In, " %d", Id->GetId(j)); - } - fprintf(In, "\n"); - } - fclose(In); -} - -//============================================================================= -/*! - * - */ -//============================================================================= -void SMESHGUI::AddNodes(SMESH_Actor * Mactor, int number, - const SMESH::double_array & coords, const SMESH::long_array & indexes) -{ - //MESSAGE("SMESHGUI::AddNodes(number="<GetMapper() == NULL) - { - vtkPoints *Pts = vtkPoints::New(); - SMESH_Grid *ugrid = SMESH_Grid::New(); - ugrid->Allocate(); - - int i = 1; - int j = 1; - while (i <= number) - { - int idVTK = - Pts->InsertNextPoint(coords[j - 1], coords[j], coords[j + 1]); - //Mactor->AddNode( indexes[i-1], idVTK ); - ugrid->AddNode(indexes[i - 1], idVTK); - i++; - j = j + 3; - } - //vtkUnstructuredGrid *ugrid = vtkUnstructuredGrid::New(); - ugrid->SetPoints(Pts); - vtkDataSetMapper *PtsMapper = vtkDataSetMapper::New(); - PtsMapper->SetInput(ugrid); - Mactor->DataSource = PtsMapper->GetInput(); - Mactor->SetMapper(PtsMapper); - } - else - { - //vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource ); - SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource); - int i = 1; - int j = 1; - while (i <= number) - { - int idVTK = - ugrid->GetPoints()->InsertNextPoint(coords[j - 1], coords[j], - coords[j + 1]); - ugrid->AddNode(indexes[i - 1], idVTK); - i++; - j = j + 3; - } - vtkDataSetMapper *PtsMapper = vtkDataSetMapper::New(); - PtsMapper->SetInput(ugrid); - Mactor->DataSource = PtsMapper->GetInput(); - Mactor->SetMapper(PtsMapper); - } - QApplication::restoreOverrideCursor(); -} - -//============================================================================= -/*! - * - */ -//============================================================================= -void SMESHGUI::AddNode(SMESH_Actor * Mactor, int idnode, float x, float y, - float z) -{ - QApplication::setOverrideCursor(Qt::waitCursor); - MESSAGE("SMESHGUI::AddNode " << idnode << " : " << x << ";" << y << ";" << z); - - if (Mactor->GetMapper() == NULL) - { - vtkPoints *Pts = vtkPoints::New(); - int idVTK = Pts->InsertNextPoint(x, y, z); - //Mactor->AddNode( idnode, idVTK ); - //vtkUnstructuredGrid *ugrid = vtkUnstructuredGrid::New(); - SMESH_Grid *ugrid = SMESH_Grid::New(); - ugrid->Allocate(); - ugrid->AddNode(idnode, idVTK); - ugrid->SetPoints(Pts); - vtkDataSetMapper *PtsMapper = vtkDataSetMapper::New(); - PtsMapper->SetInput(ugrid); - Mactor->DataSource = PtsMapper->GetInput(); - Mactor->SetMapper(PtsMapper); - } - else - { - //vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource ); - SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource); - int idVTK = ugrid->GetPoints()->InsertNextPoint(x, y, z); - //Mactor->AddNode( idnode, idVTK ); - ugrid->AddNode(idnode, idVTK); - vtkDataSetMapper *PtsMapper = vtkDataSetMapper::New(); - PtsMapper->SetInput(ugrid); - Mactor->DataSource = PtsMapper->GetInput(); - Mactor->SetMapper(PtsMapper); - } - QApplication::restoreOverrideCursor(); -} - -//============================================================================= -/*! - * - */ -//============================================================================= -void SMESHGUI::RemoveNode(SMESH_Actor * Mactor, int idnode) -{ - MESSAGE(" OLD RemoveNode method ") -// int id = Mactor->GetIdVTKNode( idnode ); -// MESSAGE ( " RemoveNode id VTK " << id ) -// if ( Mactor->GetMapper() != NULL ) { -// vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource ); -// vtkUnstructuredGrid* newUgrid = vtkUnstructuredGrid::New(); -// vtkPoints *Pts = ugrid->GetPoints(); -// vtkPoints *newPts = vtkPoints::New(); -// int nbPts = Pts->GetNumberOfPoints(); -// bool findPt = false; -// for ( int i = 0; i < nbPts; i++ ) { -// if ( id != i ) { -// if ( !findPt) -// newPts->InsertPoint(i, Pts->GetPoint(i) ); -// else -// newPts->InsertPoint(i-1, Pts->GetPoint(i) ); -// } else { -// findPt = true; -// Mactor->RemoveNode( idnode ); -// } -// } -// newUgrid->SetPoints(newPts); -// int nbCells = ugrid->GetNumberOfCells(); -// for ( int i = 0; i < nbCells; i++ ) { -// vtkIdList *Ids = ugrid->GetCell(i)->GetPointIds(); -// vtkIdList *newIds = vtkIdList::New(); -// int nbIds = Ids->GetNumberOfIds(); -// newIds->SetNumberOfIds(nbIds); -// for ( int j = 0; j < nbIds; j++ ) { -// int theid = Ids->GetId(j); -// if ( theid > id ) { -// newIds->SetId( j, theid-1 ); -// } else -// newIds->SetId( j, theid ); -// } -// int idSMDSel = Mactor->GetIdSMESHDSElement( i ); -// Mactor->RemoveElement( idSMDSel, false ); -// int idVTKel = newUgrid->InsertNextCell( ugrid->GetCell(i)->GetCellType(), newIds ); -// Mactor->AddElement( idSMDSel, idVTKel ); -// } -// vtkDataSetMapper *Mapper = vtkDataSetMapper::New(); -// Mapper->SetInput( newUgrid ); -// Mactor->DataSource = Mapper->GetInput(); -// Mactor->SetMapper(Mapper); -// UpdateView(); -// } -} - -//============================================================================= -/*! - * - */ -//============================================================================= -void SMESHGUI::RemoveNodes(SMESH_Actor * Mactor, int number, - const SMESH::double_array & coords, const SMESH::long_array & indexes) -{ - QApplication::setOverrideCursor(Qt::waitCursor); - int i = 1; - while (i <= number) - { - Mactor->RemoveNode(indexes[i - 1]); - i++; - } - - TColStd_DataMapOfIntegerInteger newMapVTKNodes; - TColStd_DataMapOfIntegerInteger newMapSMESHDSNodes; - TColStd_DataMapOfIntegerInteger MapOldNodesToNewNodes; - - if (Mactor->GetMapper() != NULL) - { - SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource); - SMESH_Grid *newUgrid = SMESH_Grid::New(); - newUgrid->CopyMaps(ugrid); - - vtkPoints *Pts = ugrid->GetPoints(); - vtkPoints *newPts = vtkPoints::New(); - int nbPts = Pts->GetNumberOfPoints(); - int j = 0; - for (int i = 0; i < nbPts; i++) - { - int idSMESHDSNode = Mactor->GetIdSMESHDSNode(i); - if (idSMESHDSNode != -1) - { - newPts->InsertPoint(j, Pts->GetPoint(i)); - - newMapVTKNodes.Bind(j, idSMESHDSNode); - newMapSMESHDSNodes.Bind(idSMESHDSNode, j); - - MapOldNodesToNewNodes.Bind(i, j); - j++; - } - } - - newUgrid->SetIdsVTKNode(newMapVTKNodes); - newUgrid->SetIdsSMESHDSNode(newMapSMESHDSNodes); - newUgrid->SetPoints(newPts); - - TColStd_DataMapOfIntegerInteger newMapElementSMDStoVTK; - TColStd_DataMapOfIntegerInteger newMapElementVTKtoSMDS; - - int nbCells = ugrid->GetNumberOfCells(); - for (int i = 0; i < nbCells; i++) - { - vtkIdList *Ids = ugrid->GetCell(i)->GetPointIds(); - vtkIdList *newIds = vtkIdList::New(); - int nbIds = Ids->GetNumberOfIds(); - newIds->SetNumberOfIds(nbIds); - bool isGood = true; - for (int j = 0; j < nbIds; j++) - { - int theid = Ids->GetId(j); - if (MapOldNodesToNewNodes.IsBound(theid)) - { - newIds->SetId(j, MapOldNodesToNewNodes.Find(theid)); - } - else - { - isGood = false; - break; - } - } - - // Filtering out cells based on non-existing nodes - if (isGood) - { - int idSMDSel = Mactor->GetIdSMESHDSElement(i); - int idVTKel = - newUgrid->InsertNextCell(ugrid->GetCell(i)->GetCellType(), - newIds); - - newMapElementSMDStoVTK.Bind(idSMDSel, idVTKel); - newMapElementVTKtoSMDS.Bind(idVTKel, idSMDSel); - } - } - - newUgrid->SetIdsVTKElement(newMapElementVTKtoSMDS); - newUgrid->SetIdsSMESHDSElement(newMapElementSMDStoVTK); - - // Copy new data to the old DatSource: keep the single DataSource for all actors - ugrid->DeepCopy(newUgrid); - - vtkDataSetMapper *Mapper = vtkDataSetMapper::New(); - Mapper->SetInput(ugrid); - Mactor->SetMapper(Mapper); - - // Commented to avoid multiple viewer updates when called by ReadScript() - //UpdateView(); - - } - QApplication::restoreOverrideCursor(); -} + QAD_MessageBox::warn1(QAD_Application::getDesktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"), + tr("SMESH_BUT_OK")); + } + break; + } + + case 5000: // HYPOTHESIS + { + if(checkLock(aStudy)) break; + smeshGUI->EmitSignalDeactivateDialog(); + SMESHGUI_CreateHypothesesDlg *aDlg = + new SMESHGUI_CreateHypothesesDlg (parent, "", FALSE, false); + break; + } + case 5010: // ALGO + { + if(checkLock(aStudy)) break; + smeshGUI->EmitSignalDeactivateDialog(); + SMESHGUI_CreateHypothesesDlg *aDlg = + new SMESHGUI_CreateHypothesesDlg (parent, "", FALSE, true); + break; + } + + case 6016: // CONTROLS + case 6015: + case 6014: + case 6013: + case 6012: + case 6011: + case 6001: + case 6003: + case 6004: + if ( smeshGUI->myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK ) { + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + if ( Sel->IObjectCount() == 1 && Sel->firstIObject()->hasEntry() ) { + SALOMEDS::SObject_var SO = smeshGUI->myStudy->FindObjectID( Sel->firstIObject()->getEntry() ); + if ( !SO->_is_nil() ) { + CORBA::Object_var aObject = SO->GetObject(); + SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( aObject ); + SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( aObject ); + SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow( aObject ); + if ( !aMesh->_is_nil() || !aSubMesh->_is_nil() || !aGroup->_is_nil() ) { + smeshGUI->Control( theCommandID ); + break; + } + } + } + QAD_MessageBox::warn1(smeshGUI->GetDesktop(), + tr( "SMESH_WRN_WARNING" ), + tr( "SMESH_BAD_SELECTION" ), + tr( "SMESH_BUT_OK" ) ); + break; + } + else { + QAD_MessageBox::warn1(smeshGUI->GetDesktop(), + tr( "SMESH_WRN_WARNING" ), + tr( "NOT_A_VTK_VIEWER" ), + tr( "SMESH_BUT_OK" ) ); + } + break; + case 9010: + { + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + if (Sel->IObjectCount() == 1) { + Handle(SALOME_InteractiveObject) anIObject = Sel->firstIObject(); + if(anIObject->hasEntry()) + if(SMESH_Actor *anActor = ::FindActorByEntry(anIObject->getEntry())){ + anActor->SetPointsLabeled( !anActor->GetPointsLabeled() ); + } + } + break; + } + case 9011: + { + SALOME_Selection *Sel = SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + if (Sel->IObjectCount() == 1) { + Handle(SALOME_InteractiveObject) anIObject = Sel->firstIObject(); + if(anIObject->hasEntry()) + if(SMESH_Actor *anActor = ::FindActorByEntry(anIObject->getEntry())){ + anActor->SetCellsLabeled( !anActor->GetCellsLabeled() ); + } + } + break; + } + case 10001: // DISPLAY MODE PREFERENCE + { + // Wireframe + parent->menuBar()->setItemChecked(10001, true); + parent->menuBar()->setItemChecked(10002, false); + parent->menuBar()->setItemChecked(10004, false); + parent->menuBar()->setItemEnabled(10003, true); + QAD_CONFIG->addSetting("SMESH:DisplayMode", "Wireframe"); + break; + } + case 10002: + { + parent->menuBar()->setItemChecked(10002, true); + parent->menuBar()->setItemChecked(10001, false); + parent->menuBar()->setItemChecked(10004, false); + parent->menuBar()->setItemEnabled(10003, true); + QAD_CONFIG->addSetting("SMESH:DisplayMode", "Shading"); + break; + } + case 10003: + { + parent->menuBar()->setItemChecked(10003,!parent->menuBar()->isItemChecked(10003)); + QAD_CONFIG->addSetting("SMESH:Shrink", parent->menuBar()->isItemChecked(10003) ? "yes" : "no"); + break; + } + case 10004: + { + parent->menuBar()->setItemChecked(10001, false); + parent->menuBar()->setItemChecked(10004, true); + parent->menuBar()->setItemChecked(10002, false); + parent->menuBar()->setItemEnabled(10003, false); + QAD_CONFIG->addSetting("SMESH:DisplayMode", "Nodes"); + break; + } + + } + + smeshGUI->myActiveStudy->updateObjBrowser(true); + return true; +} //============================================================================= -/*! - * +/*! function : GetMeshesUsingAlgoOrHypothesis() + * purpose : return a list of Study objects (mesh kind) that have 'AlgoOrHyp' affected. + * : However is supposed here that father of father of an hypothesis is a Mesh Object. */ -//============================================================================= -void SMESHGUI::RemoveNodes(SMESH::SMESH_Mesh_ptr aMesh, - const TColStd_MapOfInteger & MapIndex) +//============================================================================= +SALOMEDS::Study::ListOfSObject * + SMESHGUI::GetMeshesUsingAlgoOrHypothesis(SMESH:: + SMESH_Hypothesis_ptr AlgoOrHyp) { - QApplication::setOverrideCursor(Qt::waitCursor); - Standard_Boolean result; - SMESH_Actor *ac = FindActor(aMesh, result, true); - if (result) - { - SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array; - anArrayOfIdeces->length(MapIndex.Extent()); - TColStd_MapIteratorOfMapOfInteger ite(MapIndex); - int i = 0; - for (; ite.More(); ite.Next()) - { - // MESSAGE ( " RemoveNode : id " << ac->GetIdSMESHDSNode(ite.Key()) ) - anArrayOfIdeces[i] = ac->GetIdSMESHDSNode(ite.Key()); - i++; - } - SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor(); - aMeshEditor->RemoveNodes(anArrayOfIdeces); - - } - if (myAutomaticUpdate) - { - SMESH_Actor *Mesh = smeshGUI->ReadScript(aMesh); - if (Mesh != NULL) - { - smeshGUI->DisplayActor(Mesh); - smeshGUI->DisplayEdges(Mesh); - smeshGUI->ChangeRepresentation(Mesh, Mesh->getDisplayMode()); - AddActorInSelection(Mesh); - } + SALOMEDS::Study::ListOfSObject_var listSOmesh = + new SALOMEDS::Study::ListOfSObject; + listSOmesh->length(0); + unsigned int index = 0; + if (!AlgoOrHyp->_is_nil()) { + SALOMEDS::SObject_var SO_Hypothesis = + smeshGUI->GetStudyAPI().FindObject(AlgoOrHyp); + if (!SO_Hypothesis->_is_nil()) { + SALOMEDS::Study::ListOfSObject_var listSO = + smeshGUI->myStudy->FindDependances(SO_Hypothesis); + MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency number ="<length()); + for (unsigned int i = 0; i < listSO->length(); i++) { + SALOMEDS::SObject_ptr SO = listSO[i]; + if (!SO->_is_nil()) { + SALOMEDS::SObject_var aFather = SO->GetFather(); + if (!aFather->_is_nil()) { + SALOMEDS::SObject_var SOfatherFather = aFather->GetFather(); + if (!SOfatherFather->_is_nil()) { + MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency added to list"); + index++; + listSOmesh->length(index); + listSOmesh[index - 1] = SOfatherFather; + } + } } - QApplication::restoreOverrideCursor(); -} - -//============================================================================= -/*! - * - */ -//============================================================================= -void SMESHGUI::RemoveElement(SMESH_Actor * Mactor, int idelement) -{ - MESSAGE(" OLD RemoveElement method ") -// int id = Mactor->GetIdVTKElement( idelement ); -// MESSAGE ( " RemoveElement id VTK : " << id ) -// if ( Mactor->GetMapper() != NULL ) { -// vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource ); -// vtkUnstructuredGrid* newUgrid = vtkUnstructuredGrid::New(); -// int nbCells = ugrid->GetNumberOfCells(); -// for ( int i = 0; i < nbCells; i++ ) { -// if ( id != i ) { -// newUgrid->InsertNextCell( ugrid->GetCell(i)->GetCellType(), -// ugrid->GetCell(i)->GetPointIds() ); -// } else -// Mactor->RemoveElement( idelement ); -// } -// newUgrid->SetPoints(ugrid->GetPoints()); -// vtkDataSetMapper *Mapper = vtkDataSetMapper::New(); -// Mapper->SetInput( newUgrid ); -// Mactor->DataSource = Mapper->GetInput(); -// Mactor->SetMapper(Mapper); -// UpdateView(); -// } + } + } + } + MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): completed"); + return listSOmesh._retn(); } //============================================================================= -/*! - * - */ -//============================================================================= -void SMESHGUI::RemoveElements(SMESH_Actor * Mactor, int number, - const SMESH::double_array & coords, const SMESH::long_array & indexes) -{ - QApplication::setOverrideCursor(Qt::waitCursor); - int i = 1; - while (i <= number) - { - Mactor->RemoveElement(indexes[i - 1]); - i++; - } - TColStd_DataMapOfIntegerInteger newMapElementSMDStoVTK; - TColStd_DataMapOfIntegerInteger newMapElementVTKtoSMDS; - - if (Mactor->GetMapper() != NULL) - { - SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource); - SMESH_Grid *newUgrid = SMESH_Grid::New(); - newUgrid->CopyMaps(ugrid); - - int nbCells = ugrid->GetNumberOfCells(); - for (int i = 0; i < nbCells; i++) - { - int idSMESHDSElement = Mactor->GetIdSMESHDSElement(i); - if (idSMESHDSElement != -1) - { - int newId = - newUgrid->InsertNextCell(ugrid->GetCell(i)->GetCellType(), - ugrid->GetCell(i)->GetPointIds()); - newMapElementSMDStoVTK.Bind(idSMESHDSElement, newId); - newMapElementVTKtoSMDS.Bind(newId, idSMESHDSElement); - } - } - - newUgrid->SetIdsVTKElement(newMapElementVTKtoSMDS); - newUgrid->SetIdsSMESHDSElement(newMapElementSMDStoVTK); - - newUgrid->SetPoints(ugrid->GetPoints()); - - // Copy new data to the old DatSource: keep the single DataSource for all actors - ugrid->DeepCopy(newUgrid); - - vtkDataSetMapper *Mapper = vtkDataSetMapper::New(); - Mapper->SetInput(ugrid); - Mactor->SetMapper(Mapper); - - // Commented to avoid multiple viewer updates when called by ReadScript() - //UpdateView(); - } - QApplication::restoreOverrideCursor(); +/*! + * + */ +//============================================================================= +void SMESHGUI::Import_Mesh(QAD_Desktop * parent, int theCommandID){ + QString filter; + string myExtension; + + if(theCommandID == 113){ + filter = tr("MED files (*.med)"); + }else if (theCommandID == 112){ + filter = tr("IDEAS files (*.unv)"); + }else if (theCommandID == 111){ + filter = tr("DAT files (*.dat)"); + } + QString filename = QAD_FileDlg::getFileName(parent, + "", + filter, + tr("Import mesh"), + true); + if(!filename.isEmpty()){ + QAD_WaitCursor wc; + SMESH::mesh_array_var aMeshes; + try { + SMESH::DriverMED_ReadStatus res; + aMeshes = smeshGUI->myComponentMesh->CreateMeshesFromMED(filename.latin1(), + res); + if ( res > SMESH::DRS_OK ) { + wc.stop(); + QAD_MessageBox::warn1(QAD_Application::getDesktop(), + tr("SMESH_WRN_WARNING"), + tr(QString("SMESH_DRS_%1").arg(res)), + tr("SMESH_BUT_OK")); + wc.start(); + + } + } + catch (const SALOME::SALOME_Exception& S_ex) + { + wc.stop(); + QtCatchCorbaException(S_ex); + wc.start(); + } + for ( int i = 0, n = aMeshes->length(); i < n; i++ ) { + SALOMEDS::SObject_var aMeshSO = smeshGUI->myStudyAPI.FindObject( aMeshes[i] ); + if ( !aMeshSO->_is_nil() ) { + SALOMEDS::StudyBuilder_var aBuilder = smeshGUI->myStudy->NewBuilder(); + SALOMEDS::AttributePixMap_var aPixmap = SALOMEDS::AttributePixMap::_narrow( aBuilder->FindOrCreateAttribute( aMeshSO, "AttributePixMap" ) ); + aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH_IMPORTED" ); + } + } + } } //============================================================================= @@ -4621,44 +3168,61 @@ void SMESHGUI::RemoveElements(SMESH_Actor * Mactor, int number, * */ //============================================================================= -void SMESHGUI::RemoveElements(SMESH::SMESH_Mesh_ptr aMesh, - const TColStd_MapOfInteger & MapIndex) +void SMESHGUI::Export_Mesh(QAD_Desktop * parent, int theCommandID) { - QApplication::setOverrideCursor(Qt::waitCursor); - Standard_Boolean result; - SMESH_Actor *ac = FindActor(aMesh, result, true); - if (result) - { - SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array; - anArrayOfIdeces->length(MapIndex.Extent()); - TColStd_MapIteratorOfMapOfInteger ite(MapIndex); - int i = 0; - for (; ite.More(); ite.Next()) - { - // MESSAGE ( " RemoveElement : id " << ite.Key() << "," << ac->GetIdSMESHDSElement(ite.Key()) ) - anArrayOfIdeces[i] = ac->GetIdSMESHDSElement(ite.Key()); - i++; - } - - SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor(); - aMeshEditor->RemoveElements(anArrayOfIdeces); - } - - if (myAutomaticUpdate) - { - SMESH_Actor *Mesh = smeshGUI->ReadScript(aMesh); - if (Mesh != NULL) - { - smeshGUI->DisplayActor(Mesh); - smeshGUI->DisplayEdges(Mesh); - smeshGUI->ChangeRepresentation(Mesh, Mesh->getDisplayMode()); - AddActorInSelection(Mesh); -#ifdef TRACE - Dump(Mesh); -#endif - } - } - QApplication::restoreOverrideCursor(); + SALOME_Selection *Sel = + SALOME_Selection::Selection(smeshGUI->myActiveStudy->getSelection()); + int nbSel = Sel->IObjectCount(); + if ( !nbSel ) + return; + Standard_Boolean res; + Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject(); + SMESH::SMESH_Mesh_var aMesh = smeshGUI->ConvertIOinMesh(IObject, res); + if ( res && ( nbSel == 1 || theCommandID == 122 ) ) {// MED export supports multiple meshes + QString aFilter, aTitle = tr("Export mesh"); + switch ( theCommandID ) { + case 122: + aFilter = tr("MED files (*.med)"); + break; + case 121: + aFilter = tr("DAT files (*.dat)"); + break; + case 123: + aFilter = tr("IDEAS files (*.unv)"); + break; + default: + break; + } + + QString filename = QAD_FileDlg::getFileName(parent, "", aFilter, aTitle, false); + + if ( !filename.isEmpty() ) { + // Check whether the file already exists and delete it if yes + QFile aFile( filename ); + if ( aFile.exists() ) + aFile.remove(); + + QAD_WaitCursor wc; + for ( SALOME_ListIteratorOfListIO it( Sel->StoredIObjects() ); it.More(); it.Next() ) { + aMesh = smeshGUI->ConvertIOinMesh( it.Value(), res ); + if ( res ) { + switch ( theCommandID ) { + case 122: + aMesh->ExportMED( filename.latin1(), true ); // currently, automatic groups are always created + break; + case 121: + aMesh->ExportDAT( filename.latin1() ); + break; + case 123: + aMesh->ExportUNV( filename.latin1() ); + break; + default: + break; + } + } + } + } + } } //============================================================================= @@ -4666,59 +3230,10 @@ void SMESHGUI::RemoveElements(SMESH::SMESH_Mesh_ptr aMesh, * */ //============================================================================= -void SMESHGUI::OrientationElements(SMESH::SMESH_Mesh_ptr aMesh, - const TColStd_MapOfInteger & MapIndex) +bool SMESHGUI::OnMousePress(QMouseEvent * pe, QAD_Desktop * parent, + QAD_StudyFrame * studyFrame) { - if (myActiveStudy->getActiveStudyFrame()->getTypeView() != VIEW_VTK) - return; - - vtkRenderer *theRenderer = - ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()-> - getRightFrame()->getViewFrame())->getRenderer(); - Standard_Boolean result; - SMESH_Actor *ac = FindActor(aMesh, result, true); - if (result) - { - //vtkUnstructuredGrid* UGrid = vtkUnstructuredGrid::New(); - SMESH_Grid *UGrid = SMESH_Grid::New(); - SMESH_Grid *oldGrid = SMESH_Grid::SafeDownCast(ac->DataSource); - UGrid->CopyMaps(oldGrid); - - vtkGeometryFilter *gf = vtkGeometryFilter::New(); - gf->SetInput(ac->DataSource); - - vtkPolyDataMapper *Mapper = vtkPolyDataMapper::New(); - Mapper->SetInput(gf->GetOutput()); - Mapper->Update(); - - TColStd_MapIteratorOfMapOfInteger ite(MapIndex); - for (; ite.More(); ite.Next()) - { - Mapper->GetInput()->ReverseCell(ite.Key()); - } - - UGrid->SetPoints(Mapper->GetInput()->GetPoints()); - int nbCells = Mapper->GetInput()->GetNumberOfCells(); - for (int i = 0; i < nbCells; i++) - { - UGrid->InsertNextCell(Mapper->GetInput()->GetCellType(i), - Mapper->GetInput()->GetCell(i)->GetPointIds()); - } - - // Copy new data to the old DatSource: keep the single DataSource for all actors - oldGrid->DeepCopy(UGrid); - - vtkDataSetMapper *NewMapper = vtkDataSetMapper::New(); - //NewMapper->SetInput( UGrid ); - NewMapper->SetInput(oldGrid); - NewMapper->Update(); - - //ac->DataSource = NewMapper->GetInput(); - ac->SetMapper(NewMapper); - } - vtkRenderWindow *renWin = theRenderer->GetRenderWindow(); - renWin->Render(); - QApplication::restoreOverrideCursor(); + return false; } //============================================================================= @@ -4726,174 +3241,10 @@ void SMESHGUI::OrientationElements(SMESH::SMESH_Mesh_ptr aMesh, * */ //============================================================================= -void SMESHGUI::DiagonalInversion(SMESH::SMESH_Mesh_ptr aMesh, - const TColStd_MapOfInteger & MapIndex) +bool SMESHGUI::OnMouseMove(QMouseEvent * pe, QAD_Desktop * parent, + QAD_StudyFrame * studyFrame) { - if (myActiveStudy->getActiveStudyFrame()->getTypeView() != VIEW_VTK) - return; - - QApplication::setOverrideCursor(Qt::waitCursor); - vtkRenderer *theRenderer = - ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()-> - getRightFrame()->getViewFrame())->getRenderer(); - Standard_Boolean result; - - SMESH_Actor *ac = FindActor(aMesh, result, true); - if (result) - { - //vtkUnstructuredGrid* UGrid = vtkUnstructuredGrid::New(); - SMESH_Grid *UGrid = SMESH_Grid::New(); - vtkGeometryFilter *gf = vtkGeometryFilter::New(); - gf->SetInput(ac->DataSource); - - vtkExtractEdges *edges = vtkExtractEdges::New(); - edges->SetInput(ac->DataSource); - - vtkPolyDataMapper *Mapper = vtkPolyDataMapper::New(); - Mapper->SetInput(edges->GetOutput()); - Mapper->Update(); - - int nb = Mapper->GetInput()->GetNumberOfCells(); - //MESSAGE ( "nb : " << nb ) - - TColStd_MapIteratorOfMapOfInteger ite(MapIndex); - for (; ite.More(); ite.Next()) - { - vtkCell *StartEdge = Mapper->GetInput()->GetCell(ite.Key()); - //MESSAGE( "DCQ : Edge Id = " << ite.Key()) - int CellType = StartEdge->GetCellType(); - //MESSAGE( "DCQ : Cell Type = " << CellType) - int nbPoints = StartEdge->GetNumberOfPoints(); - - //MESSAGE( "DCQ : Nb Point = " << nbPoints) - if (nbPoints == 2) - { - vtkUnstructuredGrid *StartUGrid = - vtkUnstructuredGrid::SafeDownCast(ac->DataSource); - - vtkIdList *IdCells = vtkIdList::New(); - vtkIdList *IdPoints = StartEdge->GetPointIds(); - float p1[3]; - float p2[3]; - - Mapper->GetInput()->GetPoints()->GetPoint(IdPoints->GetId(0), - p1); - Mapper->GetInput()->GetPoints()->GetPoint(IdPoints->GetId(1), - p2); - - int idp1 = StartUGrid->FindPoint(p1); - int idp2 = StartUGrid->FindPoint(p2); - - StartUGrid->GetPointCells(idp1, IdCells); - - //MESSAGE ( " pt 0 : " << IdPoints->GetId(0) ) - //MESSAGE ( " pt 1 : " << IdPoints->GetId(1) ) - - //MESSAGE ( " pt 0 : " << idp1 ) - //MESSAGE ( " pt 1 : " << idp2 ) - - vtkIdList *IdPts = vtkIdList::New(); - if (IdCells->GetNumberOfIds() >= 2) - { - int nbCells = IdCells->GetNumberOfIds(); - //MESSAGE ( " nbCells : " << nbCells ) - for (int j = 0; j < nbCells; j++) - { - StartUGrid->GetCellPoints(IdCells->GetId(j), IdPts); - if (IdPts->IsId(idp2) == -1) - { - IdCells->DeleteId(IdCells->GetId(j)); - } - } - - //MESSAGE ( " IdCells " << IdCells->GetNumberOfIds() ) - - vtkIdList *IdPts0 = vtkIdList::New(); - vtkIdList *IdPts1 = vtkIdList::New(); - - if (IdCells->GetNumberOfIds() == 2) - { - StartUGrid->GetCellPoints(IdCells->GetId(0), IdPts0); - StartUGrid->GetCellPoints(IdCells->GetId(1), IdPts1); - - //Create new faces - TColStd_MapOfInteger EndMapIndex; - for (int j = 0; j < 3; j++) - { - if (IdPts0->GetId(j) != idp1 && - IdPts0->GetId(j) != idp2) - { - EndMapIndex.Add(IdPts0->GetId(j)); - } - if (IdPts1->GetId(j) != idp1 && - IdPts1->GetId(j) != idp2) - { - EndMapIndex.Add(IdPts1->GetId(j)); - } - } - - bool MyAU = myAutomaticUpdate; - myAutomaticUpdate = false; - - EndMapIndex.Add(idp1); - TColStd_MapIteratorOfMapOfInteger ite1(EndMapIndex); - int i = 1; - while (ite1.More()) - { - if (ite1.Key() == idp1) - break; - i++; - ite1.Next(); - } - bool reverse1 = (i == 2); - this->AddFace(aMesh, EndMapIndex, reverse1); - - EndMapIndex.Remove(idp1); - EndMapIndex.Add(idp2); - TColStd_MapIteratorOfMapOfInteger ite2(EndMapIndex); - i = 1; - while (ite2.More()) - { - if (ite2.Key() == idp2) - break; - i++; - ite2.Next(); - } - bool reverse2 = (i == 2); - this->AddFace(aMesh, EndMapIndex, - !(reverse1 == reverse2)); - - myAutomaticUpdate = MyAU; - //MESSAGE ( " myAutomaticUpdate = " << MyAU ) - Mapper->Update(); - //Remove old faces - TColStd_MapOfInteger StartMapIndex; - StartMapIndex.Add(IdCells->GetId(0)); - StartMapIndex.Add(IdCells->GetId(1)); - this->RemoveElements(aMesh, StartMapIndex); - - Mapper->Update(); - } - } - } - } - - // UGrid->SetPoints( Mapper->GetInput()->GetPoints() ); - // int nbCells = Mapper->GetInput()->GetNumberOfCells(); - // for ( int i = 0; i < nbCells; i++ ) { - // UGrid->InsertNextCell( Mapper->GetInput()->GetCellType(i), Mapper->GetInput()->GetCell(i)->GetPointIds() ); - // } - - // vtkDataSetMapper *NewMapper = vtkDataSetMapper::New(); - // NewMapper->SetInput( UGrid ); - // NewMapper->Update(); - - // ac->DataSource = NewMapper->GetInput(); - // ac->SetMapper( NewMapper ); - } - vtkRenderWindow *renWin = theRenderer->GetRenderWindow(); - renWin->Render(); - QApplication::restoreOverrideCursor(); + return true; } //============================================================================= @@ -4901,29 +3252,10 @@ void SMESHGUI::DiagonalInversion(SMESH::SMESH_Mesh_ptr aMesh, * */ //============================================================================= -void SMESHGUI::AddEdges(SMESH_Actor * Mactor, int number, - const SMESH::double_array & coords, const SMESH::long_array & indexes) +bool SMESHGUI::OnKeyPress(QKeyEvent * pe, QAD_Desktop * parent, + QAD_StudyFrame * studyFrame) { - QApplication::setOverrideCursor(Qt::waitCursor); - //vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource ); - SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource); - int i = 1; - int j = 1; - while (i <= number) - { - vtkIdList *Ids = vtkIdList::New(); - Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j])); - Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 1])); - int id = ugrid->InsertNextCell(VTK_LINE, Ids); - Mactor->AddElement(indexes[j - 1], id); - i++; - j = j + 3; - } - vtkDataSetMapper *EdgeMapper = vtkDataSetMapper::New(); - EdgeMapper->SetInput(ugrid); - Mactor->DataSource = EdgeMapper->GetInput(); - Mactor->SetMapper(EdgeMapper); - QApplication::restoreOverrideCursor(); + return true; } //============================================================================= @@ -4931,26 +3263,64 @@ void SMESHGUI::AddEdges(SMESH_Actor * Mactor, int number, * */ //============================================================================= -void SMESHGUI::AddEdge(SMESH_Actor * Mactor, int idedge, int idnode1, - int idnode2) +bool SMESHGUI::SetSettings(QAD_Desktop * parent) { - QApplication::setOverrideCursor(Qt::waitCursor); - MESSAGE("SMESHGUI::AddEdge " << idedge << " : " << idnode1 << ";" << - idnode2) vtkIdList *Ids = vtkIdList::New(); - Ids->InsertNextId(Mactor->GetIdVTKNode(idnode1)); - Ids->InsertNextId(Mactor->GetIdVTKNode(idnode2)); - - //vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource ); - SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource); - int id = ugrid->InsertNextCell(VTK_LINE, Ids); - Mactor->AddElement(idedge, id); - - MESSAGE(" Edge VTK id " << id) - vtkDataSetMapper *EdgeMapper = vtkDataSetMapper::New(); - EdgeMapper->SetInput(ugrid); - Mactor->DataSource = EdgeMapper->GetInput(); - Mactor->SetMapper(EdgeMapper); - QApplication::restoreOverrideCursor(); + MESSAGE("SMESHGUI::SetSettings."); + SMESHGUI::GetOrCreateSMESHGUI(parent); + + /* Display mode */ + QString DisplayMode = "Shading"; + if ( QAD_CONFIG->hasSetting("SMESH:DisplayMode") ) + DisplayMode = QAD_CONFIG->getSetting("SMESH:DisplayMode"); + else + QAD_CONFIG->addSetting("SMESH:DisplayMode", "Shading"); + + bool Shrink = false; + if ( QAD_CONFIG->hasSetting("SMESH:Shrink") ) + Shrink = QAD_CONFIG->getSetting("SMESH:Shrink") == "yes"; + + if (DisplayMode == "Wireframe") { + // wireframe + parent->menuBar()->setItemChecked(10004, false); + parent->menuBar()->setItemChecked(10002, false); + parent->menuBar()->setItemChecked(10001, true); + parent->menuBar()->setItemEnabled(10003, true); + } + else if (DisplayMode == "Nodes") { + // poins + parent->menuBar()->setItemChecked(10004, true); + parent->menuBar()->setItemChecked(10002, false); + parent->menuBar()->setItemChecked(10001, false); + parent->menuBar()->setItemEnabled(10003, false); + } + else { + // default is shading + parent->menuBar()->setItemChecked(10004, false); + parent->menuBar()->setItemChecked(10002, true); + parent->menuBar()->setItemChecked(10001, false); + parent->menuBar()->setItemEnabled(10003, true); + } + parent->menuBar()->setItemChecked(10003, Shrink); + + /* Automatic Update */ + QString AutoUpdate = QAD_CONFIG->getSetting("SMESH:AutomaticUpdate"); + if (AutoUpdate.compare("true") == 0) { + parent->menuBar()->setItemChecked(1001, true); + smeshGUI->myAutomaticUpdate = true; + } + else { + parent->menuBar()->setItemChecked(1001, false); + smeshGUI->myAutomaticUpdate = false; + } + + /* Selection */ + ::UpdateSelectionProp(); + + /* menus disable */ + parent->menuBar()->setItemEnabled(111, false); // IMPORT DAT + parent->menuBar()->setItemEnabled(112, false); // IMPORT UNV + + return true; } //============================================================================= @@ -4958,53 +3328,33 @@ void SMESHGUI::AddEdge(SMESH_Actor * Mactor, int idedge, int idnode1, * */ //============================================================================= -void SMESHGUI::AddTriangles(SMESH_Actor * Mactor, int number, - const SMESH::double_array & coords, const SMESH::long_array & indexes) -{ -// MESSAGE("SMESHGUI::AddTriangles(number="<DataSource ); - SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource); - int i = 1; - int j = 1; - while (i <= number) - { - vtkIdList *Ids = vtkIdList::New(); - Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j])); - Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 1])); - Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 2])); - int id = ugrid->InsertNextCell(VTK_TRIANGLE, Ids); - Mactor->AddElement(indexes[j - 1], id); - i++; - j = j + 4; - } - vtkDataSetMapper *TriMapper = vtkDataSetMapper::New(); - TriMapper->SetInput(ugrid); - Mactor->DataSource = TriMapper->GetInput(); - Mactor->SetMapper(TriMapper); - QApplication::restoreOverrideCursor(); -} -void SMESHGUI::AddTriangle(SMESH_Actor * Mactor, int idtri, int idnode1, - int idnode2, int idnode3) +void SMESHGUI::DefinePopup(QString & theContext, QString & theParent, QString & theObject) { - QApplication::setOverrideCursor(Qt::waitCursor); - vtkIdList *Ids = vtkIdList::New(); - Ids->InsertNextId(Mactor->GetIdVTKNode(idnode1)); - Ids->InsertNextId(Mactor->GetIdVTKNode(idnode2)); - Ids->InsertNextId(Mactor->GetIdVTKNode(idnode3)); - - //vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource ); - SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource); - int id = ugrid->InsertNextCell(VTK_TRIANGLE, Ids); - Mactor->AddElement(idtri, id); - - vtkDataSetMapper *TriMapper = vtkDataSetMapper::New(); - TriMapper->SetInput(ugrid); - Mactor->DataSource = TriMapper->GetInput(); - Mactor->SetMapper(TriMapper); - QApplication::restoreOverrideCursor(); + // NRI : Temporary added + // if ( smeshGUI->myStudy->GetProperties()->IsLocked() ) { + // theObject = "NothingSelected"; + // theContext = "NothingSelected"; + // } + // NRI + + SALOME_Selection *Sel = SALOME_Selection::Selection( smeshGUI->myActiveStudy->getSelection() ); + int nbSel = Sel->IObjectCount(); + switch ( nbSel ) { + case 0: + theObject = "NothingSelected"; + theContext = "NothingSelected"; + break; + case 1: + if ( smeshGUI->myState == 800 && Sel->HasIndex( Sel->firstIObject() ) ) + theObject = "Elements"; + else + theObject = smeshGUI->CheckTypeObject( Sel->firstIObject() ); + theContext = ""; + break; + default: + theObject = smeshGUI->CheckHomogeneousSelection(); + theContext = ""; + } } //============================================================================= @@ -5012,58 +3362,250 @@ void SMESHGUI::AddTriangle(SMESH_Actor * Mactor, int idtri, int idnode1, * */ //============================================================================= -void SMESHGUI::AddQuadrangles(SMESH_Actor * Mactor, int number, - const SMESH::double_array & coords, const SMESH::long_array & indexes) +bool SMESHGUI::CustomPopup(QAD_Desktop* parent, QPopupMenu* popup, const QString& theContext, + const QString& theParent, const QString& theObject) { - QApplication::setOverrideCursor(Qt::waitCursor); - //vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource ); - SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource); - int i = 1; - int j = 1; - while (i <= number) - { - vtkIdList *Ids = vtkIdList::New(); - Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j])); - Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 1])); - Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 2])); - Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 3])); - int id = ugrid->InsertNextCell(VTK_QUAD, Ids); - Mactor->AddElement(indexes[j - 1], id); - i++; - j = j + 5; - } - vtkDataSetMapper *QuadMapper = vtkDataSetMapper::New(); - QuadMapper->SetInput(ugrid); - Mactor->DataSource = QuadMapper->GetInput(); - Mactor->SetMapper(QuadMapper); - QApplication::restoreOverrideCursor(); + // get active study frame + QAD_StudyFrame* studyFrame = smeshGUI->myActiveStudy->getActiveStudyFrame(); + + // get parent component which selected object(s) belongs to + QString parentComp = ( (SALOMEGUI_Desktop*)parent )->getComponentFromSelection(); + + // get selection + SALOME_Selection* Sel = SALOME_Selection::Selection( smeshGUI->myActiveStudy->getSelection() ); + int nbSel = Sel->IObjectCount(); + + if ( nbSel == 0 ) { + popup->clear(); + } + else if ( nbSel == 1 ) { + if ( parentComp != parent->getActiveComponent() ) { + // object not belongs to SMESH module - remove all commands except common Display/Erase... + while ( 1 ) { + int id = popup->idAt( 0 ); + if ( id <= QAD_TopLabel_Popup_ID ) + popup->removeItemAt( 0 ); + else + break; + } + } + else { + // get selected interactive object + Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject(); + SALOMEDS::SObject_var SO = smeshGUI->myStudy->FindObjectID( IObject->getEntry() ); + // find popup menu's TopLabel item + int topItem = popup->indexOf( QAD_TopLabel_Popup_ID ); + if ( topItem >= 0 ) { + if ( theParent == "Viewer" ) { + // set bold font for popup menu's TopLabel item (Viewer popup) + QFont fnt = QApplication::font(); fnt.setBold( TRUE ); + popup->removeItem( QAD_TopLabel_Popup_ID ); + popup->insertItem( new CustomItem( QString( IObject->getName() ), fnt ), QAD_TopLabel_Popup_ID, topItem ); + } + else if ( theParent == "ObjectBrowser" ) { + // remove popup menu's TopLabel item (Object Browser popup) + popup->removeItem( QAD_TopLabel_Popup_ID ); + } + } + + // remove "Display only" command for component object + if ( theObject.compare( "Component" ) == 0 ) { + popup->removeItem( QAD_DisplayOnly_Popup_ID ); + } + else if ( theObject == "Hypothesis" || theObject == "Algorithm" ) { + // remove Display/Erase commands + popup->removeItem( QAD_Display_Popup_ID ); + popup->removeItem( QAD_DisplayOnly_Popup_ID ); + popup->removeItem( QAD_Erase_Popup_ID ); + // remove "Unassign ..." command if hyp/algo is not assigned + if ( SO->_is_nil() || !IObject->hasReference()/* !IsReferencedObject( SO ) */) + popup->removeItem( 1102 ); + } + else if ( theObject == "Mesh" || theObject == "SubMesh" || theObject == "Group" ) { + // get actor + GEOM::GEOM_Shape_var aShape = GetSMESHGUI()->GetStudyAPI().GetShapeOnMeshOrSubMesh( SO ); + if ( aShape->_is_nil() ) { + // imported mesh + popup->removeItem( 701 ); // Compute + popup->removeItem( 705 ); // Edit hypothesis + popup->removeItem( 706 ); // ... + } + SMESH_Actor* ac = ::FindActorByEntry(IObject->getEntry()); + // if object has actor + if ( ac && studyFrame->getTypeView() == VIEW_VTK ) { + VTKViewer_RenderWindowInteractor* myRenderInter = + ( ( VTKViewer_ViewFrame* ) studyFrame->getRightFrame()->getViewFrame() )->getRWInteractor(); + if ( myRenderInter->isVisible( IObject ) ) { + popup->removeItem( QAD_Display_Popup_ID ); + popup->setItemChecked( 9010, ac->GetPointsLabeled() ); // Numbering / Display Nodes # + popup->setItemChecked( 9011, ac->GetCellsLabeled() ); // Numbering / Display Elements # + TVisualObjPtr aVisualObj = ac->GetObject(); + int aNbEdges = aVisualObj->GetNbEntities(SMESH::EDGE); + int aNbFaces = aVisualObj->GetNbEntities(SMESH::FACE); + int aNbVolumes = aVisualObj->GetNbEntities(SMESH::VOLUME); + QMenuItem* mi = popup->findItem( 1131 ); + if ( mi && mi->popup() ) { + int prType = ac->GetRepresentation(); + // Display Mode / Wireframe + if(!aNbFaces && !aNbVolumes && !aNbEdges){ + mi->popup()->removeItem( 211 ); + }else{ + mi->popup()->setItemChecked( 211, prType == SMESH_Actor::eEdge ); + } + // Display Mode / Shading + if(!aNbFaces && !aNbVolumes){ + mi->popup()->removeItem( 212 ); + }else{ + mi->popup()->setItemChecked( 212, prType == SMESH_Actor::eSurface ); + } + // Display Mode / Points + mi->popup()->setItemChecked( 215, prType == SMESH_Actor::ePoint ); + // Display Mode / Shrink + bool isShrunk = ac->IsShrunk(); + bool isShrunkable = ac->IsShrunkable(); + mi->popup()->setItemChecked( 213, isShrunk ); + mi->popup()->setItemEnabled( 213, prType != SMESH_Actor::ePoint && isShrunkable); + } + // Scalar Bar + mi = popup->findItem( 2000 ); + if ( mi && mi->popup() ) { + SMESH_Actor::eControl cMode = ac->GetControlMode(); + switch ( cMode ) { + case SMESH_Actor::eLengthEdges: + mi->popup()->setItemChecked( 6001, true ); break; + case SMESH_Actor::eFreeBorders: + mi->popup()->setItemChecked( 6003, true ); + mi->popup()->removeItem( 201 ); + break; + case SMESH_Actor::eMultiConnection: + mi->popup()->setItemChecked( 6004, true ); break; + case SMESH_Actor::eArea: + mi->popup()->setItemChecked( 6011, true ); break; + case SMESH_Actor::eTaper: + mi->popup()->setItemChecked( 6012, true ); break; + case SMESH_Actor::eAspectRatio: + mi->popup()->setItemChecked( 6013, true ); break; + case SMESH_Actor::eMinimumAngle: + mi->popup()->setItemChecked( 6014, true ); break; + case SMESH_Actor::eWarping: + mi->popup()->setItemChecked( 6015, true ); break; + case SMESH_Actor::eSkew: + mi->popup()->setItemChecked( 6016, true ); break; + case SMESH_Actor::eNone: + default: + mi->popup()->removeItem( 200 ); + mi->popup()->removeItem( 201 ); + break; + } + TVisualObjPtr aVisualObj = ac->GetObject(); + SMESH::ElementType aType; + if(!aNbEdges){ + mi->popup()->removeItem( 6001 ); + mi->popup()->removeItem( 6003 ); + mi->popup()->removeItem( 6004 ); + } + if(!aNbFaces){ + mi->popup()->removeItem( 6011 ); + mi->popup()->removeItem( 6012 ); + mi->popup()->removeItem( 6013 ); + mi->popup()->removeItem( 6014 ); + mi->popup()->removeItem( 6015 ); + mi->popup()->removeItem( 6016 ); + } + if(!aNbFaces && !aNbEdges) + popup->removeItem( 2000 ); // Scalar Bar + } + } + else { + popup->removeItem( QAD_Erase_Popup_ID ); + popup->removeItem( 114 ); // Numbering popup menu + popup->removeItem( 1131 ); // Display mode + popup->removeItem( 1132 ); // Color / size + popup->removeItem( 1133 ); // Transparency + popup->removeItem( 2000 ); // Scalar Bar + } + } + else { + // object doesn't have actor + CORBA::Object_var anObject = SO->GetObject(); + bool bDisplay = false; + if ( !CORBA::is_nil( anObject ) ) { + SMESH::SMESH_Mesh_var aMeshObj = SMESH::SMESH_Mesh::_narrow( anObject ); + if ( !aMeshObj->_is_nil() && ( aMeshObj->NbNodes() > 0 || aMeshObj->NbFaces() > 0 || aMeshObj->NbVolumes() > 0 ) ) + bDisplay = true; + SMESH::SMESH_subMesh_var aSubMeshObj = SMESH::SMESH_subMesh::_narrow( anObject ); + if ( !aSubMeshObj->_is_nil() && ( aSubMeshObj->GetNumberOfNodes() > 0 || aSubMeshObj->GetNumberOfElements() > 0 ) ) + bDisplay = true; + SMESH::SMESH_Group_var aGroupObj = SMESH::SMESH_Group::_narrow( anObject ); + if ( !aGroupObj->_is_nil() && aGroupObj->Size() > 0 ) + bDisplay = true; + } + if ( !bDisplay ) { + popup->removeItem( QAD_Display_Popup_ID ); + popup->removeItem( QAD_DisplayOnly_Popup_ID ); + } + popup->removeItem( QAD_Erase_Popup_ID ); + popup->removeItem( 114 ); // Numbering popup menu + popup->removeItem( 1131 ); // Display mode + popup->removeItem( 1132 ); // Color / size + popup->removeItem( 1133 ); // Transparency + popup->removeItem( 2000 ); // Scalar Bar + } + } + else { + // another SMESH object + popup->removeItem( QAD_Display_Popup_ID ); + popup->removeItem( QAD_DisplayOnly_Popup_ID ); + popup->removeItem( QAD_Erase_Popup_ID ); + } + } + } + else { + // multiple selection + if ( parentComp != parent->getActiveComponent() ) { + // object not belongs to SMESH module - remove all commands except common Display/Erase... + while ( 1 ) { + int id = popup->idAt( 0 ); + if ( id <= QAD_TopLabel_Popup_ID ) + popup->removeItemAt( 0 ); + else + break; + } + if ( parentComp.isNull() ) { + // objects from different components are selected + popup->removeItem( QAD_DisplayOnly_Popup_ID ); + popup->removeItem( QAD_Display_Popup_ID ); + popup->removeItem( QAD_Erase_Popup_ID ); + } + } + else { + QString type = smeshGUI->CheckHomogeneousSelection(); + if ( type != "Heterogeneous Selection" ) { + int topItem = popup->indexOf( QAD_TopLabel_Popup_ID ); + if ( topItem >= 0 ) { + // set bold font for popup menu's TopLabel item + QFont fnt = QApplication::font(); fnt.setBold( TRUE ); + popup->removeItem( QAD_TopLabel_Popup_ID ); + popup->insertItem( new CustomItem( QString("%1 ").arg( nbSel ) + type + "(s) ", fnt ), QAD_TopLabel_Popup_ID, topItem ); + } + } + } + } + return false; } //============================================================================= -/*! - * +/*! Method: BuildPresentation(const Handle(SALOME_InteractiveObject)& theIO) + * Purpose: ensures that the actor for the given exists in the active VTK view */ //============================================================================= -void SMESHGUI::AddQuadrangle(SMESH_Actor * Mactor, int idquad, int idnode1, - int idnode2, int idnode3, int idnode4) +void SMESHGUI::BuildPresentation(const Handle(SALOME_InteractiveObject) & theIO) { - QApplication::setOverrideCursor(Qt::waitCursor); - vtkIdList *Ids = vtkIdList::New(); - Ids->InsertNextId(Mactor->GetIdVTKNode(idnode1)); - Ids->InsertNextId(Mactor->GetIdVTKNode(idnode2)); - Ids->InsertNextId(Mactor->GetIdVTKNode(idnode3)); - Ids->InsertNextId(Mactor->GetIdVTKNode(idnode4)); - - //vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource ); - SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource); - int id = ugrid->InsertNextCell(VTK_QUAD, Ids); - Mactor->AddElement(idquad, id); - - vtkDataSetMapper *QuadMapper = vtkDataSetMapper::New(); - QuadMapper->SetInput(ugrid); - Mactor->DataSource = QuadMapper->GetInput(); - Mactor->SetMapper(QuadMapper); - QApplication::restoreOverrideCursor(); + if(theIO->hasEntry()){ + QAD_Study* aStudy = SMESHGUI::GetSMESHGUI()->GetActiveStudy(); + QAD_StudyFrame *aStudyFrame = aStudy->getActiveStudyFrame(); + ::UpdateView(aStudyFrame,eDisplay,theIO->getEntry()); + } } //============================================================================= @@ -5071,31 +3613,19 @@ void SMESHGUI::AddQuadrangle(SMESH_Actor * Mactor, int idquad, int idnode1, * */ //============================================================================= -void SMESHGUI::AddTetras(SMESH_Actor * Mactor, int number, - const SMESH::double_array & coords, const SMESH::long_array & indexes) +void SMESHGUI::setOrb() { - QApplication::setOverrideCursor(Qt::waitCursor); - //vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource ); - SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource); - int i = 1; - int j = 1; - while (i <= number) + try { - vtkIdList *Ids = vtkIdList::New(); - Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j])); - Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 1])); - Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 2])); - Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 3])); - int id = ugrid->InsertNextCell(VTK_TETRA, Ids); - Mactor->AddElement(indexes[j - 1], id); - i++; - j = j + 5; + ORB_INIT & init = *SINGLETON_ < ORB_INIT >::Instance(); + ASSERT(SINGLETON_ < ORB_INIT >::IsAlreadyExisting()); + _orb = init(0, 0); + } catch(...) + { + INFOS("internal error : orb not found"); + _orb = 0; } - vtkDataSetMapper *TetraMapper = vtkDataSetMapper::New(); - TetraMapper->SetInput(ugrid); - Mactor->DataSource = TetraMapper->GetInput(); - Mactor->SetMapper(TetraMapper); - QApplication::restoreOverrideCursor(); + ASSERT(!CORBA::is_nil(_orb)); } //============================================================================= @@ -5103,65 +3633,41 @@ void SMESHGUI::AddTetras(SMESH_Actor * Mactor, int number, * */ //============================================================================= -void SMESHGUI::AddTetra(SMESH_Actor * Mactor, int idtetra, int idnode1, - int idnode2, int idnode3, int idnode4) -{ - QApplication::setOverrideCursor(Qt::waitCursor); - MESSAGE("SMESHGUI::AddTetra " << idtetra << " : " << idnode1 << ";" << - idnode2 << ";" << idnode3 << ";" << idnode4) vtkIdList *Ids = - vtkIdList::New(); - Ids->InsertNextId(Mactor->GetIdVTKNode(idnode1)); - Ids->InsertNextId(Mactor->GetIdVTKNode(idnode2)); - Ids->InsertNextId(Mactor->GetIdVTKNode(idnode3)); - Ids->InsertNextId(Mactor->GetIdVTKNode(idnode4)); - - //vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource ); - SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource); - int id = ugrid->InsertNextCell(VTK_TETRA, Ids); - Mactor->AddElement(idtetra, id); - - MESSAGE(" Tetra VTK id " << id) - vtkDataSetMapper *TetraMapper = vtkDataSetMapper::New(); - TetraMapper->SetInput(ugrid); - Mactor->DataSource = TetraMapper->GetInput(); - Mactor->SetMapper(TetraMapper); - QApplication::restoreOverrideCursor(); -} +SMESH_Actor *SMESHGUI::ReadScript(SMESH::SMESH_Mesh_ptr theMesh){} //============================================================================= /*! * */ //============================================================================= -void SMESHGUI::AddHexaedres(SMESH_Actor * Mactor, int number, - const SMESH::double_array & coords, const SMESH::long_array & indexes) +void SMESHGUI::Dump(SMESH_Actor * Mactor) { - QApplication::setOverrideCursor(Qt::waitCursor); - //vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource ); - SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource); - int i = 1; - int j = 1; - while (i <= number) + vtkUnstructuredGrid *ugrid = Mactor->GetUnstructuredGrid(); + vtkPoints *Pts = ugrid->GetPoints(); + int nbPts = Pts->GetNumberOfPoints(); + int nbCells = ugrid->GetNumberOfCells(); + + FILE *In; + int i, j; + In = fopen("/tmp/dumpMesh", "w+"); + fprintf(In, "%d %d\n", nbPts, nbCells); + for (int i = 0; i < nbPts; i++) { - vtkIdList *Ids = vtkIdList::New(); - Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j])); - Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 1])); - Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 2])); - Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 3])); - Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 4])); - Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 5])); - Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 6])); - Ids->InsertNextId(Mactor->GetIdVTKNode(indexes[j + 7])); - int id = ugrid->InsertNextCell(VTK_HEXAHEDRON, Ids); - Mactor->AddElement(indexes[j - 1], id); - i++; - j = j + 9; + float *p = ugrid->GetPoint(i); + fprintf(In, "%d %e %e %e\n", i, p[0], p[1], p[2]); + } + + for (int i = 0; i < nbCells; i++) + { + fprintf(In, "%d %d", i, ugrid->GetCell(i)->GetCellType()); + vtkIdList *Id = ugrid->GetCell(i)->GetPointIds(); + for (j = 0; j < Id->GetNumberOfIds(); j++) + { + fprintf(In, " %d", Id->GetId(j)); + } + fprintf(In, "\n"); } - vtkDataSetMapper *HexaMapper = vtkDataSetMapper::New(); - HexaMapper->SetInput(ugrid); - Mactor->DataSource = HexaMapper->GetInput(); - Mactor->SetMapper(HexaMapper); - QApplication::restoreOverrideCursor(); + fclose(In); } //============================================================================= @@ -5169,101 +3675,73 @@ void SMESHGUI::AddHexaedres(SMESH_Actor * Mactor, int number, * */ //============================================================================= -void SMESHGUI::AddHexaedre(SMESH_Actor * Mactor, int idhexa, int idnode1, - int idnode2, int idnode3, int idnode4, int idnode5, int idnode6, - int idnode7, int idnode8) +void SMESHGUI::RemoveNodes(SMESH::SMESH_Mesh_ptr theMesh, + const TColStd_MapOfInteger & MapIndex) { - QApplication::setOverrideCursor(Qt::waitCursor); - MESSAGE("SMESHGUI::AddHexaedre " << idhexa << " : " << idnode1 << ";" << - idnode2 << ";" << idnode3 << ";" << idnode4 << ";" << idnode5 << ";" << - idnode6 << ";" << idnode7 << ";" << idnode8) vtkIdList *Ids = - vtkIdList::New(); - Ids->InsertNextId(Mactor->GetIdVTKNode(idnode1)); - Ids->InsertNextId(Mactor->GetIdVTKNode(idnode2)); - Ids->InsertNextId(Mactor->GetIdVTKNode(idnode3)); - Ids->InsertNextId(Mactor->GetIdVTKNode(idnode4)); - Ids->InsertNextId(Mactor->GetIdVTKNode(idnode5)); - Ids->InsertNextId(Mactor->GetIdVTKNode(idnode6)); - Ids->InsertNextId(Mactor->GetIdVTKNode(idnode7)); - Ids->InsertNextId(Mactor->GetIdVTKNode(idnode8)); - - //vtkUnstructuredGrid *ugrid = vtkUnstructuredGrid::SafeDownCast( Mactor->DataSource ); - SMESH_Grid *ugrid = SMESH_Grid::SafeDownCast(Mactor->DataSource); - int id = ugrid->InsertNextCell(VTK_HEXAHEDRON, Ids); - Mactor->AddElement(idhexa, id); - - MESSAGE(" Hexa VTK id " << id) - vtkDataSetMapper *HexaMapper = vtkDataSetMapper::New(); - HexaMapper->SetInput(ugrid); - Mactor->DataSource = HexaMapper->GetInput(); - Mactor->SetMapper(HexaMapper); - QApplication::restoreOverrideCursor(); + QAD_WaitCursor wc; + try{ + SALOMEDS::SObject_var aSobj = myStudyAPI.FindObject(theMesh); + CORBA::String_var anEntry = aSobj->GetID(); + if(SMESH_Actor* anActor = ::FindActorByEntry(anEntry.in())){ + SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array; + anArrayOfIdeces->length(MapIndex.Extent()); + TColStd_MapIteratorOfMapOfInteger ite(MapIndex); + for(int i = 0; ite.More(); ite.Next(), i++){ + anArrayOfIdeces[i] = anActor->GetNodeObjId(ite.Key()); + } + SMESH::SMESH_MeshEditor_var aMeshEditor = theMesh->GetMeshEditor(); + aMeshEditor->RemoveNodes(anArrayOfIdeces); + if(myAutomaticUpdate){ + CORBA::Long anId = smeshGUI->myStudy->StudyId(); + if(TVisualObjPtr aVisualObj = GetVisualObj(anId,anEntry.in())){ + aVisualObj->Update(true); + } + } + } + }catch(SALOME::SALOME_Exception& exc) { + INFOS("Follow exception was cought:\n\t"<GetID(); + if(SMESH_Actor* anActor = ::FindActorByEntry(anEntry.in())){ + SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array; + anArrayOfIdeces->length(MapIndex.Extent()); + TColStd_MapIteratorOfMapOfInteger ite(MapIndex); + for(int i = 0; ite.More(); ite.Next(), i++){ + anArrayOfIdeces[i] = anActor->GetElemObjId(ite.Key()); + } + SMESH::SMESH_MeshEditor_var aMeshEditor = theMesh->GetMeshEditor(); + aMeshEditor->RemoveElements(anArrayOfIdeces); + if(myAutomaticUpdate){ + CORBA::Long anId = smeshGUI->myStudy->StudyId(); + if(TVisualObjPtr aVisualObj = GetVisualObj(anId,anEntry.in())){ + aVisualObj->Update(true); + } + } + } + }catch(SALOME::SALOME_Exception& exc) { + INFOS("Follow exception was cought:\n\t"<getActiveStudyFrame()->getTypeView() != VIEW_VTK) - return; - - EraseSimulationActors(); - mySimulationActors = vtkActorCollection::New(); - vtkRenderer *theRenderer = - ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()-> - getRightFrame()->getViewFrame())->getRenderer(); - vtkActorCollection *theActors = theRenderer->GetActors(); - theActors->InitTraversal(); - vtkActor *ac = theActors->GetNextActor(); - while (!(ac == NULL)) - { - if (ac->IsA("SMESH_Actor")) - { - SMESH_Actor *anActor = SMESH_Actor::SafeDownCast(ac); - if (anActor->GetVisibility() == 1) - { - vtkGeometryFilter *gf = vtkGeometryFilter::New(); - gf->SetInput(anActor->DataSource); - vtkMaskPoints *verts = vtkMaskPoints::New(); - verts->SetInput(gf->GetOutput()); - verts->GenerateVerticesOn(); - verts->SetOnRatio(1); - - vtkPolyDataMapper *vertMapper = vtkPolyDataMapper::New(); - vertMapper->SetInput(verts->GetOutput()); - vertMapper->ScalarVisibilityOff(); - - vtkActor *vertActor = vtkActor::New(); - vertActor->SetMapper(vertMapper); - - float r, g, b; - anActor->GetNodeColor(r, g, b); - vertActor->GetProperty()->SetColor(r, g, b); - - vertActor->GetProperty()->SetPointSize(anActor->GetNodeSize()); - - vertActor->PickableOff(); - - mySimulationActors->AddItem(vertActor); - theRenderer->AddActor(vertActor); - } - } - ac = theActors->GetNextActor(); - } - - vtkRenderWindow *renWin = theRenderer->GetRenderWindow(); - renWin->Render(); + MESSAGE("OrientationElements - not implemeted yet!"); } //============================================================================= @@ -5329,193 +3760,58 @@ void SMESHGUI::ViewNodes() * */ //============================================================================= -void SMESHGUI::Control(int theCommandID) +void SMESHGUI::DiagonalInversion(SMESH::SMESH_Mesh_ptr aMesh, + const TColStd_MapOfInteger & MapIndex) { - if (myActiveStudy->getActiveStudyFrame()->getTypeView() != VIEW_VTK) - return; - - QApplication::setOverrideCursor(Qt::waitCursor); - DisplayScalarBar(false); - - vtkDoubleArray *scalars = vtkDoubleArray::New(); - scalars->SetNumberOfComponents(1); - - vtkDataSetMapper *meshMapper = 0; - SALOME_Selection *Sel = - SALOME_Selection::Selection(myActiveStudy->getSelection()); - int nbSel = Sel->IObjectCount(); - Standard_Boolean result; - Handle(SALOME_InteractiveObject) IObject = Sel->firstIObject(); - SMESH_Actor *MeshActor = - FindActorByEntry(IObject->getEntry(), result, true); - - // Mesh may be not updated after Compute - if (!MeshActor->DataSource || !MeshActor->GetMapper()) - { - QApplication::restoreOverrideCursor(); - return; - } - - vtkDataSet *aDataSet = MeshActor->DataSource; - typedef double (*TScalarFun) (vtkCell * theCell); - TScalarFun aScalarFun; - if (result) - { - QString type; - switch (theCommandID) - { - case 6001: - { - type = tr("SMESH_CONTROL_LENGTH_EDGES"); - aDataSet = MeshActor->EdgeDevice->GetMapper()->GetInput(); - aScalarFun = &(SMESHGUI_ComputeScalarValue::LengthEdges); - MESSAGE(" init minimum length " << aDataSet->GetNumberOfCells()); - if (MeshActor->getDisplayMode() != 0) - ChangeRepresentation(MeshActor, 1); // limitation; in Wireframe, colored edges are not visible - break; - } - case 6011: - { - type = tr("SMESH_CONTROL_AREA_ELEMENTS"); - aScalarFun = &(SMESHGUI_ComputeScalarValue::AreaElements); - if (MeshActor->getDisplayMode() != 1) - ChangeRepresentation(MeshActor, 1); - break; - } - case 6012: - { - type = tr("SMESH_CONTROL_TAPER_ELEMENTS"); - aScalarFun = &(SMESHGUI_ComputeScalarValue::Taper); - break; - } - case 6013: - { - type = tr("SMESH_CONTROL_ASPECTRATIO_ELEMENTS"); - aScalarFun = &(SMESHGUI_ComputeScalarValue::AspectRatio); - if (MeshActor->getDisplayMode() != 1) - ChangeRepresentation(MeshActor, 1); - break; - } - case 6014: - { - type = tr("SMESH_CONTROL_MINIMUMANGLE_ELEMENTS"); - aScalarFun = &(SMESHGUI_ComputeScalarValue::MinimumAngle); - if (MeshActor->getDisplayMode() != 1) - ChangeRepresentation(MeshActor, 1); - break; - } - case 6015: - { - type = tr("SMESH_CONTROL_WARP_ELEMENTS"); - aScalarFun = &(SMESHGUI_ComputeScalarValue::Warp); - break; - } - case 6016: - { - type = tr("SMESH_CONTROL_SKEW_ELEMENTS"); - aScalarFun = &(SMESHGUI_ComputeScalarValue::Skew); - break; - } - } - - for (int i = 0, iEnd = aDataSet->GetNumberOfCells(); i < iEnd; i++) - scalars->InsertTuple1(i, aScalarFun(aDataSet->GetCell(i))); - - float range[2]; - scalars->GetRange(range); - - vtkLookupTable *wat = vtkLookupTable::New(); - wat->SetRange(range); - wat->Build(); - - scalars->SetLookupTable(wat); - - if (!meshMapper) - meshMapper = (vtkDataSetMapper *) (MeshActor->getMapper()); - meshMapper->SetScalarModeToUseCellData(); - MeshActor->DataSource->GetCellData()->SetScalars(scalars); - meshMapper->SetScalarRange(range); - meshMapper->ScalarVisibilityOn(); + MESSAGE("OrientationElements - not implemeted yet!"); +} - vtkScalarBarActor *aScalarBar = GetScalarBar(); - if (aScalarBar == NULL) - { - aScalarBar = vtkScalarBarActor::New(); - QString Bold = QAD_CONFIG->getSetting("ScalarBar:Bold"); - QString Italic = QAD_CONFIG->getSetting("ScalarBar:Italic"); - QString Shadow = QAD_CONFIG->getSetting("ScalarBar:Shadow"); - QString FontFamily = QAD_CONFIG->getSetting("ScalarBar:FontFamily"); - QString Orientation = - QAD_CONFIG->getSetting("ScalarBar:Orientation"); - float Width = QAD_CONFIG->getSetting("ScalarBar:Width").toFloat(); - float Height = QAD_CONFIG->getSetting("ScalarBar:Height").toFloat(); - int NumberOfLabels = - QAD_CONFIG->getSetting("ScalarBar:NumberOfLabels").toInt(); - int NumberOfColors = - QAD_CONFIG->getSetting("ScalarBar:NumberOfColors").toInt(); - - SetSettingsScalarBar(aScalarBar, Bold, Italic, Shadow, FontFamily, - Orientation, Width, Height, NumberOfColors, NumberOfLabels); - vtkRenderer *theRenderer = - ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()-> - getRightFrame()->getViewFrame())->getRenderer(); - theRenderer->AddActor2D(aScalarBar); - } - aScalarBar->SetLookupTable(wat); - aScalarBar->SetTitle(type.latin1()); +//===================================================================================== +// EXPORTED METHODS +//===================================================================================== +void SMESHGUI::SupportedViewType(int *buffer, int bufferSize) +{ + if (!buffer || !bufferSize) + return; + buffer[0] = (int)VIEW_VTK; +} - scalars->Delete(); - // wat->Delete(); - DisplayScalarBar(true); - } - QApplication::restoreOverrideCursor(); +void SMESHGUI::Deactivate() +{ + if ( SMESHGUI::GetSMESHGUI() ) { + SMESHGUI::GetSMESHGUI()->EmitSignalCloseAllDialogs(); + } } + //============================================================================= /*! * */ //============================================================================= -void SMESHGUI::SetSettingsScalarBar(vtkScalarBarActor * theScalarBar, - QString Bold, QString Italic, - QString Shadow, QString FontFamily, - QString Orientation, float Width, float Height, int NbColors, int NbLabels) -{ - if (Bold.isNull() || Bold.isEmpty() || (Bold.compare("true") == 0)) - theScalarBar->BoldOn(); - else - theScalarBar->BoldOff(); - - if (Italic.isNull() || Italic.isEmpty() || (Italic.compare("true") == 0)) - theScalarBar->ItalicOn(); - else - theScalarBar->ItalicOff(); - - if (Shadow.isNull() || Shadow.isEmpty() || (Shadow.compare("true") == 0)) - theScalarBar->ShadowOn(); - else - theScalarBar->ShadowOff(); - - if (FontFamily.compare("Arial") == 0) - theScalarBar->SetFontFamilyToArial(); - else if (FontFamily.compare("Courier") == 0) - theScalarBar->SetFontFamilyToCourier(); - else if (FontFamily.compare("Times") == 0) - theScalarBar->SetFontFamilyToTimes(); - else - theScalarBar->SetFontFamilyToArial(); - - if (Orientation.isNull() || Orientation.isEmpty() || - (Orientation.compare("Vertical") == 0)) - theScalarBar->SetOrientationToVertical(); - else - theScalarBar->SetOrientationToHorizontal(); +void SMESHGUI::SetPickable(SMESH_Actor* theActor){ + if(VTKViewer_ViewFrame* aViewFrame = GetCurrentVtkView()){ + int anIsAllPickable = (theActor == NULL); + vtkRenderer *aRenderer = aViewFrame->getRenderer(); + vtkActorCollection *aCollection = aRenderer->GetActors(); + aCollection->InitTraversal(); + while(vtkActor *anAct = aCollection->GetNextActor()){ + if(SALOME_Actor *anActor = dynamic_cast(anAct)){ + if(anActor->GetVisibility()){ + anActor->SetPickable(anIsAllPickable); + } + } + } + if(theActor) + theActor->SetPickable(!anIsAllPickable); + RepaintCurrentView(); + } +} - theScalarBar->SetWidth((Width == 0) ? 0.17 : Width); - theScalarBar->SetHeight((Height == 0) ? 0.8 : Height); - theScalarBar->SetNumberOfLabels((NbLabels == 0) ? 5 : NbLabels); - theScalarBar->SetMaximumNumberOfColors((NbColors == 0) ? 64 : NbColors); +void SMESHGUI::ViewNodes(){ + EraseSimulationActors(); + ::SetPointRepresentation(true); } //============================================================================= @@ -5523,58 +3819,57 @@ void SMESHGUI::SetSettingsScalarBar(vtkScalarBarActor * theScalarBar, * */ //============================================================================= -void SMESHGUI::DisplayScalarBar(bool visibility) -{ - if (myActiveStudy->getActiveStudyFrame()->getTypeView() != VIEW_VTK) - return; - - vtkRenderer *theRenderer = - ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()-> - getRightFrame()->getViewFrame())->getRenderer(); - vtkScalarBarActor *aScalarBar = GetScalarBar(); - - if (aScalarBar == NULL) - { - MESSAGE("myScalarBar is NULL"); - return; - } - - if (visibility) - aScalarBar->VisibilityOn(); - else - { - aScalarBar->VisibilityOff(); - //Turn off mesh coloring (influences on all views) - vtkActorCollection *actorList = theRenderer->GetActors(); - actorList->InitTraversal(); - vtkActor *ac = actorList->GetNextActor(); - while (ac != NULL) - { - if (ac->GetMapper() != NULL) - { - ac->GetMapper()->ScalarVisibilityOff(); - } - ac = actorList->GetNextActor(); - } - // Turn off ScalarBar in all views - /*QList aFrames = myActiveStudy->getStudyFrames(); - * for ( QAD_StudyFrame* aFrame = aFrames.first(); aFrame; aFrame = aFrames.next() ) { - * if (aFrame->getTypeView() == VIEW_VTK) { - * vtkRenderer *aRenderer = ((VTKViewer_ViewFrame*) aFrame->getRightFrame()->getViewFrame())->getRenderer(); - * vtkActor2DCollection* actor2DList = aRenderer->GetActors2D(); - * actor2DList->InitTraversal(); - * vtkActor2D* aActor2d = actor2DList->GetNextActor2D(); - * while (aActor2d != NULL) { - * if (aActor2d->IsA("vtkScalarBarActor")) { - * aActor2d->VisibilityOff(); - * break; - * } - * actor2DList->GetNextActor2D(); - * } - * } - * } */ +void SMESHGUI::Control( int theCommandID ){ + SALOME_Selection *Sel = SALOME_Selection::Selection( myActiveStudy->getSelection() ); + if(Sel){ + Handle(SALOME_InteractiveObject) anIO = Sel->firstIObject(); + if(!anIO.IsNull()){ + QString aTitle; + SMESH_Actor::eControl aControl = SMESH_Actor::eNone; + if(SMESH_Actor *anActor = ::FindActorByEntry(anIO->getEntry())){ + switch ( theCommandID ){ + case 6001: + aTitle = tr( "LENGTH_EDGES" ); + aControl = SMESH_Actor::eLengthEdges; + break; + case 6003: + aTitle = tr( "FREE_BORDERS" ); + aControl = SMESH_Actor::eFreeBorders; + break; + case 6004: + aTitle = tr( "MULTI_BORDERS" ); + aControl = SMESH_Actor::eMultiConnection; + break; + case 6011: + aTitle = tr( "AREA_ELEMENTS" ); + aControl = SMESH_Actor::eArea; + break; + case 6012: + aTitle = tr( "TAPER_ELEMENTS" ); + aControl = SMESH_Actor::eTaper; + break; + case 6013: + aTitle = tr( "ASPECTRATIO_ELEMENTS" ); + aControl = SMESH_Actor::eAspectRatio; + break; + case 6014: + aTitle = tr( "MINIMUMANGLE_ELEMENTS" ); + aControl = SMESH_Actor::eMinimumAngle; + break; + case 6015: + aTitle = tr( "WARP_ELEMENTS" ); + aControl = SMESH_Actor::eWarping; + break; + case 6016: + aTitle = tr( "SKEW_ELEMENTS" ); + aControl = SMESH_Actor::eSkew; + break; } - myActiveStudy->update3dViewers(); + anActor->SetControlMode(aControl); + anActor->GetScalarBarActor()->SetTitle(aTitle.latin1()); + } + } + } } //============================================================================= @@ -5582,39 +3877,52 @@ void SMESHGUI::DisplayScalarBar(bool visibility) * */ //============================================================================= -void SMESHGUI::UpdateScalarBar(float MinRange, float MaxRange) +void SMESHGUI::SetSettingsScalarBar(vtkScalarBarActor * theScalarBar, + QString Bold, + QString Italic, + QString Shadow, + QString FontFamily, + QString Orientation, + float Width, + float Height, + int NbColors, + int NbLabels) { - vtkScalarBarActor *aScalarBar = GetScalarBar(); - if (aScalarBar == NULL) - { - MESSAGE("myScalarBar is NULL"); - return; - } - DisplayScalarBar(false); - - aScalarBar->GetLookupTable()->SetRange(MinRange, MaxRange); - vtkRenderer *aRenderer = - ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()-> - getRightFrame()->getViewFrame())->getRenderer(); - vtkActorCollection *aActorList = aRenderer->GetActors(); - aActorList->InitTraversal(); - vtkActor *aActor = aActorList->GetNextActor(); - while (aActor != NULL) - { - if (aActor->IsA("SMESH_Actor")) - { - SMESH_Actor *aMeshActor = SMESH_Actor::SafeDownCast(aActor); - vtkDataSetMapper *aMeshMapper = - (vtkDataSetMapper *) (aMeshActor->getMapper()); - if ((aMeshMapper != NULL)) - { - aMeshMapper->SetScalarRange(MinRange, MaxRange); - aMeshMapper->ScalarVisibilityOn(); - } - } - aActor = aActorList->GetNextActor(); - } - DisplayScalarBar(true); + if (Bold.isNull() || Bold.isEmpty() || (Bold.compare("true") == 0)) + theScalarBar->BoldOn(); + else + theScalarBar->BoldOff(); + + if (Italic.isNull() || Italic.isEmpty() || (Italic.compare("true") == 0)) + theScalarBar->ItalicOn(); + else + theScalarBar->ItalicOff(); + + if (Shadow.isNull() || Shadow.isEmpty() || (Shadow.compare("true") == 0)) + theScalarBar->ShadowOn(); + else + theScalarBar->ShadowOff(); + + if (FontFamily.compare("Arial") == 0) + theScalarBar->SetFontFamilyToArial(); + else if (FontFamily.compare("Courier") == 0) + theScalarBar->SetFontFamilyToCourier(); + else if (FontFamily.compare("Times") == 0) + theScalarBar->SetFontFamilyToTimes(); + else + theScalarBar->SetFontFamilyToArial(); + + if (Orientation.isNull() || Orientation.isEmpty() || + (Orientation.compare("Vertical") == 0)) + theScalarBar->SetOrientationToVertical(); + else + theScalarBar->SetOrientationToHorizontal(); + + theScalarBar->SetWidth((Width == 0) ? 0.17 : Width); + theScalarBar->SetHeight((Height == 0) ? 0.8 : Height); + + theScalarBar->SetNumberOfLabels((NbLabels == 0) ? 5 : NbLabels); + theScalarBar->SetMaximumNumberOfColors((NbColors == 0) ? 64 : NbColors); } //============================================================================= @@ -5624,82 +3932,86 @@ void SMESHGUI::UpdateScalarBar(float MinRange, float MaxRange) //============================================================================= void SMESHGUI::SetDisplaySettings() { - EmitSignalDeactivateDialog(); - SMESHGUI_Preferences_ColorDlg *aDlg = - new SMESHGUI_Preferences_ColorDlg(QAD_Application::getDesktop(), ""); - - QString SCr = QAD_CONFIG->getSetting("SMESH:SettingsFillColorRed"); - QString SCg = QAD_CONFIG->getSetting("SMESH:SettingsFillColorGreen"); - QString SCb = QAD_CONFIG->getSetting("SMESH:SettingsFillColorBlue"); - QColor color = QColor(SCr.toInt(), SCg.toInt(), SCb.toInt()); - aDlg->SetColor(1, color); - - SCr = QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorRed"); - SCg = QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorGreen"); - SCb = QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorBlue"); - color = QColor(SCr.toInt(), SCg.toInt(), SCb.toInt()); - aDlg->SetColor(2, color); - - SCr = QAD_CONFIG->getSetting("SMESH:SettingsNodeColorRed"); - SCg = QAD_CONFIG->getSetting("SMESH:SettingsNodeColorGreen"); - SCb = QAD_CONFIG->getSetting("SMESH:SettingsNodeColorBlue"); - color = QColor(SCr.toInt(), SCg.toInt(), SCb.toInt()); - aDlg->SetColor(3, color); - - QString SBr = QAD_CONFIG->getSetting("SMESH:SettingsBackFaceColorRed"); - QString SBg = QAD_CONFIG->getSetting("SMESH:SettingsBackFaceColorGreen"); - QString SBb = QAD_CONFIG->getSetting("SMESH:SettingsBackFaceColorBlue"); - color = QColor(SBr.toInt(), SBg.toInt(), SBb.toInt()); - aDlg->SetColor(4, color); - - QString intValue = QAD_CONFIG->getSetting("SMESH:SettingsWidth"); - aDlg->SetIntValue(1, intValue.toInt()); - intValue = QAD_CONFIG->getSetting("SMESH:SettingsNodesSize"); - aDlg->SetIntValue(2, intValue.toInt()); - intValue = QAD_CONFIG->getSetting("SMESH:SettingsShrinkCoeff"); - aDlg->SetIntValue(3, intValue.toInt()); - - if (aDlg->exec()) - { - QColor colorFill = aDlg->GetColor(1); - QAD_CONFIG->addSetting("SMESH:SettingsFillColorRed", colorFill.red()); - QAD_CONFIG->addSetting("SMESH:SettingsFillColorGreen", - colorFill.green()); - QAD_CONFIG->addSetting("SMESH:SettingsFillColorBlue", colorFill.blue()); - - QColor colorOutline = aDlg->GetColor(2); - QAD_CONFIG->addSetting("SMESH:SettingsOutlineColorRed", - colorOutline.red()); - QAD_CONFIG->addSetting("SMESH:SettingsOutlineColorGreen", - colorOutline.green()); - QAD_CONFIG->addSetting("SMESH:SettingsOutlineColorBlue", - colorOutline.blue()); - - QColor colorNode = aDlg->GetColor(3); - QAD_CONFIG->addSetting("SMESH:SettingsNodeColorRed", colorNode.red()); - QAD_CONFIG->addSetting("SMESH:SettingsNodeColorGreen", - colorNode.green()); - QAD_CONFIG->addSetting("SMESH:SettingsNodeColorBlue", colorNode.blue()); - - QColor colorBackFace = aDlg->GetColor(4); - QAD_CONFIG->addSetting("SMESH:SettingsBackFaceColorRed", - colorBackFace.red()); - QAD_CONFIG->addSetting("SMESH:SettingsBackFaceColorGreen", - colorBackFace.green()); - QAD_CONFIG->addSetting("SMESH:SettingsBackFaceColorBlue", - colorBackFace.blue()); - - int width = aDlg->GetIntValue(1); - QAD_CONFIG->addSetting("SMESH:SettingsWidth", width); - - int nodes_size = aDlg->GetIntValue(2); - QAD_CONFIG->addSetting("SMESH:SettingsNodesSize", nodes_size); - - int shrink_coeff = aDlg->GetIntValue(3); - QAD_CONFIG->addSetting("SMESH:SettingsShrinkCoeff", shrink_coeff); - } - - delete aDlg; + EmitSignalDeactivateDialog(); + SMESHGUI_Preferences_ColorDlg *aDlg = + new SMESHGUI_Preferences_ColorDlg(QAD_Application::getDesktop(), ""); + + QColor color; + QString SCr, SCg, SCb; + SCr = QAD_CONFIG->getSetting("SMESH:SettingsFillColorRed"); + SCg = QAD_CONFIG->getSetting("SMESH:SettingsFillColorGreen"); + SCb = QAD_CONFIG->getSetting("SMESH:SettingsFillColorBlue"); + if (!SCr.isEmpty() && !SCg.isEmpty() && !SCb.isEmpty()) + color = QColor(SCr.toInt(), SCg.toInt(), SCb.toInt()); + else color = QColor(0, 170, 255); + aDlg->SetColor(1, color); + + SCr = QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorRed"); + SCg = QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorGreen"); + SCb = QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorBlue"); + if (!SCr.isEmpty() && !SCg.isEmpty() && !SCb.isEmpty()) + color = QColor(SCr.toInt(), SCg.toInt(), SCb.toInt()); + else color = QColor(0, 170, 255); + aDlg->SetColor(2, color); + + SCr = QAD_CONFIG->getSetting("SMESH:SettingsNodeColorRed"); + SCg = QAD_CONFIG->getSetting("SMESH:SettingsNodeColorGreen"); + SCb = QAD_CONFIG->getSetting("SMESH:SettingsNodeColorBlue"); + if (!SCr.isEmpty() && !SCg.isEmpty() && !SCb.isEmpty()) + color = QColor(SCr.toInt(), SCg.toInt(), SCb.toInt()); + else color = Qt::red; + aDlg->SetColor(3, color); + + QString SBr = QAD_CONFIG->getSetting("SMESH:SettingsBackFaceColorRed"); + QString SBg = QAD_CONFIG->getSetting("SMESH:SettingsBackFaceColorGreen"); + QString SBb = QAD_CONFIG->getSetting("SMESH:SettingsBackFaceColorBlue"); + if (!SCr.isEmpty() && !SCg.isEmpty() && !SCb.isEmpty()) + color = QColor(SBr.toInt(), SBg.toInt(), SBb.toInt()); + else color = Qt::blue; + aDlg->SetColor(4, color); + + QString intValue = QAD_CONFIG->getSetting("SMESH:SettingsWidth"); + if (intValue.isEmpty()) intValue = "1"; + aDlg->SetIntValue(1, intValue.toInt()); + intValue = QAD_CONFIG->getSetting("SMESH:SettingsNodesSize"); + if (intValue.isEmpty()) intValue = "3"; + aDlg->SetIntValue(2, intValue.toInt()); + intValue = QAD_CONFIG->getSetting("SMESH:SettingsShrinkCoeff"); + if (intValue.isEmpty()) intValue = "75"; + aDlg->SetIntValue(3, intValue.toInt()); + + if (aDlg->exec()) { + QColor colorFill = aDlg->GetColor(1); + QAD_CONFIG->addSetting("SMESH:SettingsFillColorRed", colorFill.red()); + QAD_CONFIG->addSetting("SMESH:SettingsFillColorGreen", colorFill.green()); + QAD_CONFIG->addSetting("SMESH:SettingsFillColorBlue", colorFill.blue()); + + QColor colorOutline = aDlg->GetColor(2); + QAD_CONFIG->addSetting("SMESH:SettingsOutlineColorRed", colorOutline.red()); + QAD_CONFIG->addSetting("SMESH:SettingsOutlineColorGreen", colorOutline.green()); + QAD_CONFIG->addSetting("SMESH:SettingsOutlineColorBlue", colorOutline.blue()); + + QColor colorNode = aDlg->GetColor(3); + QAD_CONFIG->addSetting("SMESH:SettingsNodeColorRed", colorNode.red()); + QAD_CONFIG->addSetting("SMESH:SettingsNodeColorGreen", colorNode.green()); + QAD_CONFIG->addSetting("SMESH:SettingsNodeColorBlue", colorNode.blue()); + + QColor colorBackFace = aDlg->GetColor(4); + QAD_CONFIG->addSetting("SMESH:SettingsBackFaceColorRed", colorBackFace.red()); + QAD_CONFIG->addSetting("SMESH:SettingsBackFaceColorGreen", colorBackFace.green()); + QAD_CONFIG->addSetting("SMESH:SettingsBackFaceColorBlue", colorBackFace.blue()); + + int width = aDlg->GetIntValue(1); + QAD_CONFIG->addSetting("SMESH:SettingsWidth", width); + + int nodes_size = aDlg->GetIntValue(2); + QAD_CONFIG->addSetting("SMESH:SettingsNodesSize", nodes_size); + + int shrink_coeff = aDlg->GetIntValue(3); + QAD_CONFIG->addSetting("SMESH:SettingsShrinkCoeff", shrink_coeff); + } + + delete aDlg; } //======================================================================= @@ -5766,190 +4078,43 @@ int SMESHGUI::Parameter(Standard_Boolean & res, * */ //============================================================================= -void SMESHGUI::DisplayEdges(SMESH_Actor * ac, bool visibility) -{ - if (myActiveStudy->getActiveStudyFrame()->getTypeView() != VIEW_VTK) - return; - if (ac->DataSource == NULL || ac->GetMapper() == NULL) - return; - - vtkGeometryFilter *gf = vtkGeometryFilter::New(); - gf->SetInput(ac->DataSource); - vtkFeatureEdges *edges = vtkFeatureEdges::New(); - edges->SetInput(gf->GetOutput()); - edges->BoundaryEdgesOn(); - edges->ManifoldEdgesOn(); - - vtkPolyDataMapper *edgeMapper = vtkPolyDataMapper::New(); - edgeMapper->SetInput(edges->GetOutput()); - edgeMapper->ScalarVisibilityOff(); - - vtkRenderer *theRenderer = - ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()-> - getRightFrame()->getViewFrame())->getRenderer(); - vtkActorCollection *actorList = theRenderer->GetActors(); - - int test = actorList->IsItemPresent(ac->EdgeDevice); - if (test == 0) - { - vtkProperty *prop = vtkProperty::New(); - prop->SetColor(QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorRed"). - toFloat() / 255., - QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorGreen"). - toFloat() / 255., - QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorBlue").toFloat() / - 255.); - prop->SetPointSize(QAD_CONFIG->getSetting("SMESH:SettingsNodesSize"). - toInt()); - prop->SetLineWidth(QAD_CONFIG->getSetting("SMESH:SettingsWidth"). - toInt()); - ac->EdgeDevice->SetProperty(prop); - ac->SetEdgeColor(QAD_CONFIG-> - getSetting("SMESH:SettingsOutlineColorRed").toFloat() / 255., - QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorGreen"). - toFloat() / 255., - QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorBlue").toFloat() / - 255.); - ac->EdgeDevice->SetMapper(edgeMapper); - - theRenderer->AddActor(ac->EdgeDevice); - } - else - { - ac->EdgeDevice->SetMapper(edgeMapper); - edgeMapper->Update(); - } - - vtkShrinkFilter *shrink = vtkShrinkFilter::New(); - shrink->SetInput(ac->DataSource); - shrink->SetShrinkFactor(ac->GetShrinkFactor()); - vtkGeometryFilter *Shrinkgf = vtkGeometryFilter::New(); - Shrinkgf->SetInput(shrink->GetOutput()); - vtkFeatureEdges *ShrinkEdges = vtkFeatureEdges::New(); - ShrinkEdges->SetInput(Shrinkgf->GetOutput()); - ShrinkEdges->BoundaryEdgesOn(); - ShrinkEdges->ManifoldEdgesOn(); - - vtkPolyDataMapper *ShrinkEdgeMapper = vtkPolyDataMapper::New(); - ShrinkEdgeMapper->SetInput(ShrinkEdges->GetOutput()); - ShrinkEdgeMapper->ScalarVisibilityOff(); - - test = actorList->IsItemPresent(ac->EdgeShrinkDevice); - if (test == 0) - { - vtkProperty *prop = vtkProperty::New(); - prop->SetColor(QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorRed"). - toFloat() / 255., - QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorGreen"). - toFloat() / 255., - QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorBlue").toFloat() / - 255.); - prop->SetPointSize(QAD_CONFIG->getSetting("SMESH:SettingsNodesSize"). - toInt()); - prop->SetLineWidth(QAD_CONFIG->getSetting("SMESH:SettingsWidth"). - toInt()); - ac->EdgeShrinkDevice->SetProperty(prop); - ac->SetEdgeColor(QAD_CONFIG-> - getSetting("SMESH:SettingsOutlineColorRed").toFloat() / 255., - QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorGreen"). - toFloat() / 255., - QAD_CONFIG->getSetting("SMESH:SettingsOutlineColorBlue").toFloat() / - 255.); - ac->EdgeShrinkDevice->SetMapper(ShrinkEdgeMapper); - - theRenderer->AddActor(ac->EdgeShrinkDevice); - } - else - { - ac->EdgeShrinkDevice->SetMapper(ShrinkEdgeMapper); - ShrinkEdgeMapper->Update(); - } - - vtkRenderWindow *renWin = theRenderer->GetRenderWindow(); - renWin->Render(); -} +void SMESHGUI::DisplayEdges(SMESH_Actor * ac, bool visibility){} //============================================================================= /*! * */ //============================================================================= -void SMESHGUI::InitActor(SMESH::SMESH_Mesh_ptr aMesh) -{ - SALOMEDS::SObject_var aSO_M = myStudyAPI.FindMesh(aMesh); - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::AttributeName_var aName; - if (!aSO_M->_is_nil()) - { - if (aSO_M->FindAttribute(anAttr, "AttributeName")) - { - aName = SALOMEDS::AttributeName::_narrow(anAttr); - Standard_Boolean result; - SMESH_Actor *MeshActor = - smeshGUI->FindActorByEntry(aSO_M->GetID(), result, true); - if (!result) - { - SMESH_Actor *amesh = SMESH_Actor::New(); - Handle(SALOME_InteractiveObject) IO = - new SALOME_InteractiveObject(aSO_M->GetID(), "MESH", - aName->Value()); - amesh->setIO(IO); - amesh->setName(aName->Value()); - DisplayActor(amesh, false); - } - } - } -} +void SMESHGUI::InitActor(SMESH::SMESH_Mesh_ptr aMesh){} //============================================================================= /*! * */ //============================================================================= -void SMESHGUI::Update() -{ - MESSAGE("SMESHGUI::Update"); - if (myActiveStudy->getActiveStudyFrame()->getTypeView() == VIEW_VTK) - { //VTK - vtkRenderer *theRenderer = - ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()-> - getRightFrame()->getViewFrame())->getRenderer(); - - SALOME_Selection *Sel = - SALOME_Selection::Selection(myActiveStudy->getSelection()); - int nbSel = Sel->IObjectCount(); - if (nbSel == 0) - { - vtkActorCollection *actorList = theRenderer->GetActors(); - actorList->InitTraversal(); - vtkActor *ac = actorList->GetNextActor(); - while (!(ac == NULL)) - { - if (ac->IsA("SMESH_Actor")) - { - SMESH_Actor *anActor = SMESH_Actor::SafeDownCast(ac); - if (anActor->hasIO()) - { - Handle(SALOME_InteractiveObject) IO = anActor->getIO(); - Update(IO); - } - } - ac = actorList->GetNextActor(); - } - } - else - { - SALOME_ListIteratorOfListIO It(Sel->StoredIObjects()); - for (; It.More(); It.Next()) - { - Handle(SALOME_InteractiveObject) IO = It.Value(); - Update(IO); - } - } - vtkRenderWindow *renWin = theRenderer->GetRenderWindow(); - renWin->Render(); - } - QApplication::restoreOverrideCursor(); +void SMESHGUI::Update(){ + if(VTKViewer_ViewFrame* aViewFrame = GetCurrentVtkView()){ + SALOME_Selection *Sel = SALOME_Selection::Selection(myActiveStudy->getSelection()); + if(Sel->IObjectCount() == 0){ + vtkRenderer* aRenderer = aViewFrame->getRenderer(); + vtkActorCollection *aCollection = aRenderer->GetActors(); + aCollection->InitTraversal(); + while(vtkActor *anAct = aCollection->GetNextActor()){ + if(SMESH_Actor *anActor = dynamic_cast(anAct)){ + if(anActor->hasIO()){ + Update(anActor->getIO()); + } + } + } + }else{ + SALOME_ListIteratorOfListIO It(Sel->StoredIObjects()); + for(; It.More(); It.Next()){ + Handle(SALOME_InteractiveObject) IO = It.Value(); + Update(IO); + } + } + ::RepaintCurrentView(); + } } //============================================================================= @@ -5957,47 +4122,11 @@ void SMESHGUI::Update() * */ //============================================================================= -void SMESHGUI::Update(const Handle(SALOME_InteractiveObject) & IO) -{ - if (myActiveStudy->getActiveStudyFrame()->getTypeView() != VIEW_VTK) - return; - - if (IO->hasEntry()) - { - Standard_Boolean res; - SMESH::SMESH_Mesh_var aMesh = ConvertIOinMesh(IO, res); - if (res) - { - SMESH_Actor *ac = FindActorByEntry(IO->getEntry(), res, false); - if (res) - { - // Check whether the actor belongs to the active view - VTKViewer_RenderWindowInteractor *rwInter = - ((VTKViewer_ViewFrame *) myActiveStudy-> - getActiveStudyFrame()->getRightFrame()->getViewFrame())-> - getRWInteractor(); - - ac = ReadScript(aMesh); - // The actor belongs to inactive view -> create a copy and display it in the active view - if (!rwInter->isInViewer(IO)) - { - SMESH_Actor *acCopy = SMESH_Actor::New(); - acCopy->ShallowCopy(ac); - ac=acCopy; - } - - if (ac != NULL) - { -#ifdef TRACE - Dump(ac); -#endif - DisplayActor(ac); - DisplayEdges(ac); - smeshGUI->ChangeRepresentation(ac, ac->getDisplayMode()); - } - } - } - } +void SMESHGUI::Update(const Handle(SALOME_InteractiveObject) & theIO){ + CORBA::Long anId = smeshGUI->myStudy->StudyId(); + TVisualObjPtr aVisualObj = ::GetVisualObj(anId,theIO->getEntry()); + aVisualObj->Update(); + ::UpdateView(eDisplay,theIO->getEntry()); } //============================================================================= @@ -6016,7 +4145,7 @@ vtkActor *SMESHGUI::SimulationMoveNode(SMESH_Actor * Mactor, int idnode) getRightFrame()->getViewFrame())->getRenderer(); vtkUnstructuredGrid *ugrid = - vtkUnstructuredGrid::SafeDownCast(Mactor->DataSource); + vtkUnstructuredGrid::SafeDownCast(Mactor->GetUnstructuredGrid()); vtkIdList *IdCells = vtkIdList::New(); ugrid->GetPointCells(idnode, IdCells); @@ -6037,7 +4166,7 @@ vtkActor *SMESHGUI::SimulationMoveNode(SMESH_Actor * Mactor, int idnode) prop->SetColor(1., 0., 0.); prop->SetRepresentationToWireframe(); - int Edgewidth = (int)Mactor->EdgeDevice->GetProperty()->GetLineWidth(); + int Edgewidth = (int)Mactor->GetLineWidth(); if (Edgewidth == 0) Edgewidth = 1; prop->SetLineWidth(Edgewidth + 1); @@ -6082,7 +4211,7 @@ void SMESHGUI::DisplaySimulationNode(SMESH::SMESH_Mesh_ptr aMesh, float x, if (result) { vtkUnstructuredGrid *ugrid = - vtkUnstructuredGrid::SafeDownCast(ac->DataSource); + vtkUnstructuredGrid::SafeDownCast(ac->GetUnstructuredGrid()); vtkUnstructuredGrid *newugrid = vtkUnstructuredGrid::New(); vtkPoints *Pts = ugrid->GetPoints(); @@ -6184,36 +4313,17 @@ void SMESHGUI::MoveNode(SMESH::SMESH_Mesh_ptr aMesh, int idnode, float x, * */ //============================================================================= -void SMESHGUI::ScalarVisibilityOff() -{ - if (myActiveStudy->getActiveStudyFrame()->getTypeView() != VIEW_VTK) - return; - - vtkRenderer *theRenderer = - ((VTKViewer_ViewFrame *) myActiveStudy->getActiveStudyFrame()-> - getRightFrame()->getViewFrame())->getRenderer(); - vtkActorCollection *actorList = theRenderer->GetActors(); - - actorList->InitTraversal(); - vtkActor *ac = actorList->GetNextActor(); - while (!(ac == NULL)) - { - if (ac->IsA("SMESH_Actor")) - { - SMESH_Actor *anActor = SMESH_Actor::SafeDownCast(ac); - if (anActor->GetVisibility() == 1) - { - vtkDataSetMapper *meshMapper = - (vtkDataSetMapper *) (anActor->getMapper()); - meshMapper->ScalarVisibilityOff(); - meshMapper->SetInput(anActor->DataSource); - ChangeRepresentation(anActor, anActor->getDisplayMode()); - } - } - ac = actorList->GetNextActor(); - } - - theRenderer->Render(); +void SMESHGUI::ScalarVisibilityOff(){ + if(vtkRenderer *aRenderer = ::GetCurrentRenderer()){ + vtkActorCollection *actorList = aRenderer->GetActors(); + actorList->InitTraversal(); + while(vtkActor *ac = actorList->GetNextActor()){ + if(SMESH_Actor *anActor = SMESH_Actor::SafeDownCast(ac)){ + anActor->GetMapper()->ScalarVisibilityOff(); + } + } + ::RepaintCurrentView(); + } } //============================================================================= @@ -6253,7 +4363,7 @@ void SMESHGUI::DisplaySimulationEdge(SMESH::SMESH_Mesh_ptr aMesh, pts[1] = idNodes[1]; vtkUnstructuredGrid *ugrid = - vtkUnstructuredGrid::SafeDownCast(ac->DataSource); + vtkUnstructuredGrid::SafeDownCast(ac->GetUnstructuredGrid()); vtkUnstructuredGrid *newugrid = vtkUnstructuredGrid::New(); newugrid->SetPoints(ugrid->GetPoints()); newugrid->InsertNextCell(VTK_LINE, 2, pts); @@ -6325,7 +4435,7 @@ void SMESHGUI::DisplaySimulationTriangle(SMESH::SMESH_Mesh_ptr aMesh, pts[2] = idNodes[2]; } vtkUnstructuredGrid *ugrid = - vtkUnstructuredGrid::SafeDownCast(ac->DataSource); + vtkUnstructuredGrid::SafeDownCast(ac->GetUnstructuredGrid()); vtkUnstructuredGrid *newugrid = vtkUnstructuredGrid::New(); newugrid->SetPoints(ugrid->GetPoints()); newugrid->InsertNextCell(VTK_TRIANGLE, 3, pts); @@ -6367,7 +4477,7 @@ void SMESHGUI::DisplaySimulationQuadrangle(SMESH::SMESH_Mesh_ptr aMesh, SMESH_Actor *ac = FindActor(aMesh, result, true); vtkUnstructuredGrid *ugrid = - vtkUnstructuredGrid::SafeDownCast(ac->DataSource); + vtkUnstructuredGrid::SafeDownCast(ac->GetUnstructuredGrid()); if (result) { @@ -6432,7 +4542,7 @@ void SMESHGUI::DisplaySimulationQuadrangle(SMESH::SMESH_Mesh_ptr aMesh, Ids->InsertId(3, idNodes[3]); } - // vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( ac->DataSource ); + // vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( ac->GetUnstructuredGrid() ); vtkUnstructuredGrid *newugrid = vtkUnstructuredGrid::New(); newugrid->SetPoints(ugrid->GetPoints()); newugrid->InsertNextCell(VTK_QUAD, Ids); @@ -6489,7 +4599,7 @@ void SMESHGUI::DisplaySimulationTetra(SMESH::SMESH_Mesh_ptr aMesh, Ids->InsertId(3, idNodes[3]); vtkUnstructuredGrid *ugrid = - vtkUnstructuredGrid::SafeDownCast(ac->DataSource); + vtkUnstructuredGrid::SafeDownCast(ac->GetUnstructuredGrid()); vtkUnstructuredGrid *newugrid = vtkUnstructuredGrid::New(); newugrid->SetPoints(ugrid->GetPoints()); newugrid->InsertNextCell(VTK_TETRA, Ids); @@ -6550,7 +4660,7 @@ void SMESHGUI::DisplaySimulationHexa(SMESH::SMESH_Mesh_ptr aMesh, Ids->InsertId(7, idNodes[7]); vtkUnstructuredGrid *ugrid = - vtkUnstructuredGrid::SafeDownCast(ac->DataSource); + vtkUnstructuredGrid::SafeDownCast(ac->GetUnstructuredGrid()); vtkUnstructuredGrid *newugrid = vtkUnstructuredGrid::New(); newugrid->SetPoints(ugrid->GetPoints()); newugrid->InsertNextCell(VTK_HEXAHEDRON, Ids); @@ -6576,101 +4686,84 @@ void SMESHGUI::DisplaySimulationHexa(SMESH::SMESH_Mesh_ptr aMesh, * */ //============================================================================= -void SMESHGUI::AddFace(SMESH::SMESH_Mesh_ptr aMesh, - const TColStd_MapOfInteger & MapIndex, bool reverse) +void SMESHGUI::AddFace(SMESH::SMESH_Mesh_ptr theMesh, + const TColStd_MapOfInteger & MapIndex, + bool reverse) { - QApplication::setOverrideCursor(Qt::waitCursor); - Standard_Boolean result; - SMESH_Actor *ac = FindActor(aMesh, result, true); - if (result) - { - TColStd_MapIteratorOfMapOfInteger ite(MapIndex); - SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array; - anArrayOfIdeces->length(MapIndex.Extent()); - - int i = 0; - for (; ite.More(); ite.Next()) - { - anArrayOfIdeces[i] = ac->GetIdSMESHDSNode(ite.Key()); - i++; - } - - int tmp; - if (MapIndex.Extent() == 4) - { - int idNodes[4]; - int i = 0; - TColStd_MapIteratorOfMapOfInteger ite1(MapIndex); - for (; ite1.More(); ite1.Next()) - { - idNodes[i] = ite1.Key(); - i++; - } - - vtkUnstructuredGrid *ugrid = - vtkUnstructuredGrid::SafeDownCast(ac->DataSource); - float *p0 = ugrid->GetPoint(idNodes[0]); - float *p1 = ugrid->GetPoint(idNodes[1]); - float *p2 = ugrid->GetPoint(idNodes[2]); - float *p3 = ugrid->GetPoint(idNodes[3]); - - gp_Pnt P0(p0[0], p0[1], p0[2]); - - gp_Vec V1(P0, gp_Pnt(p1[0], p1[1], p1[2])); - gp_Vec V2(P0, gp_Pnt(p2[0], p2[1], p2[2])); - gp_Vec V3(P0, gp_Pnt(p3[0], p3[1], p3[2])); - - gp_Vec Cross1 = V1 ^ V2; - gp_Vec Cross2 = V2 ^ V3; - - if (Cross1.Dot(Cross2) < 0) - { - - V1 = gp_Vec(P0, gp_Pnt(p2[0], p2[1], p2[2])); - V2 = gp_Vec(P0, gp_Pnt(p1[0], p1[1], p1[2])); - Cross1 = V1 ^ V2; - Cross2 = V2 ^ V3; - - if (Cross1.Dot(Cross2) < 0) - { - tmp = anArrayOfIdeces[2]; - anArrayOfIdeces[2] = anArrayOfIdeces[3]; - anArrayOfIdeces[3] = tmp; - } - else - { - tmp = anArrayOfIdeces[1]; - anArrayOfIdeces[1] = anArrayOfIdeces[2]; - anArrayOfIdeces[2] = tmp; - } - } - } - - // int tmp; - if (reverse) - { - for (i = 0; i < (MapIndex.Extent() / 2); i++) - { - tmp = anArrayOfIdeces[i]; - anArrayOfIdeces[i] = anArrayOfIdeces[MapIndex.Extent() - i - 1]; - anArrayOfIdeces[MapIndex.Extent() - i - 1] = tmp; - } - } - SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor(); - aMeshEditor->AddFace(anArrayOfIdeces); - } - if (myAutomaticUpdate) - { - SMESH_Actor *Mesh = smeshGUI->ReadScript(aMesh); - if (Mesh != NULL) - { - smeshGUI->DisplayActor(Mesh); - smeshGUI->DisplayEdges(Mesh); - smeshGUI->ChangeRepresentation(Mesh, Mesh->getDisplayMode()); - AddActorInSelection(Mesh); - } - } - QApplication::restoreOverrideCursor(); + QAD_WaitCursor wc; + try{ + SALOMEDS::SObject_var aSobj = myStudyAPI.FindObject(theMesh); + CORBA::String_var anEntry = aSobj->GetID(); + if(SMESH_Actor* anActor = ::FindActorByEntry(anEntry.in())){ + SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array; + anArrayOfIdeces->length(MapIndex.Extent()); + TColStd_MapIteratorOfMapOfInteger ite(MapIndex); + for(int i = 0; ite.More(); ite.Next(), i++){ + anArrayOfIdeces[i] = anActor->GetNodeObjId(ite.Key()); + } + int tmp; + if(MapIndex.Extent() == 4){ + int idNodes[4]; + TColStd_MapIteratorOfMapOfInteger ite1(MapIndex); + for(int i = 0; ite1.More(); ite1.Next(), i++){ + idNodes[i] = ite1.Key(); + } + vtkUnstructuredGrid *ugrid = anActor->GetUnstructuredGrid(); + float *p0 = ugrid->GetPoint(idNodes[0]); + float *p1 = ugrid->GetPoint(idNodes[1]); + float *p2 = ugrid->GetPoint(idNodes[2]); + float *p3 = ugrid->GetPoint(idNodes[3]); + + gp_Pnt P0(p0[0], p0[1], p0[2]); + + gp_Vec V1(P0, gp_Pnt(p1[0], p1[1], p1[2])); + gp_Vec V2(P0, gp_Pnt(p2[0], p2[1], p2[2])); + gp_Vec V3(P0, gp_Pnt(p3[0], p3[1], p3[2])); + + gp_Vec Cross1 = V1 ^ V2; + gp_Vec Cross2 = V2 ^ V3; + + if(Cross1.Dot(Cross2) < 0){ + V1 = gp_Vec(P0, gp_Pnt(p2[0], p2[1], p2[2])); + V2 = gp_Vec(P0, gp_Pnt(p1[0], p1[1], p1[2])); + Cross1 = V1 ^ V2; + Cross2 = V2 ^ V3; + + if(Cross1.Dot(Cross2) < 0){ + tmp = anArrayOfIdeces[2]; + anArrayOfIdeces[2] = anArrayOfIdeces[3]; + anArrayOfIdeces[3] = tmp; + }else{ + tmp = anArrayOfIdeces[1]; + anArrayOfIdeces[1] = anArrayOfIdeces[2]; + anArrayOfIdeces[2] = tmp; + } + } + } + if(reverse){ + for(int i = 0; i < (MapIndex.Extent() / 2); i++){ + tmp = anArrayOfIdeces[i]; + anArrayOfIdeces[i] = anArrayOfIdeces[MapIndex.Extent() - i - 1]; + anArrayOfIdeces[MapIndex.Extent() - i - 1] = tmp; + } + } + SMESH::SMESH_MeshEditor_var aMeshEditor = theMesh->GetMeshEditor(); + aMeshEditor->AddFace(anArrayOfIdeces); + if(myAutomaticUpdate){ + CORBA::Long anId = smeshGUI->myStudy->StudyId(); + if(TVisualObjPtr aVisualObj = GetVisualObj(anId,anEntry.in())){ + aVisualObj->Update(true); + } + AddActorInSelection(anActor); + } + } + }catch(SALOME::SALOME_Exception& exc) { + INFOS("Follow exception was cought:\n\t"<length(MapIndex.Extent()); - - int i = 0; - for (; ite.More(); ite.Next()) - { - anArrayOfIdeces[i] = ac->GetIdSMESHDSNode(ite.Key()); - i++; - } - - SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor(); - aMeshEditor->AddVolume(anArrayOfIdeces); - } - if (myAutomaticUpdate) - { - SMESH_Actor *Mesh = smeshGUI->ReadScript(aMesh); - if (Mesh != NULL) - { - smeshGUI->DisplayActor(Mesh); - smeshGUI->DisplayEdges(Mesh); - smeshGUI->ChangeRepresentation(Mesh, Mesh->getDisplayMode()); - AddActorInSelection(Mesh); - } - } - QApplication::restoreOverrideCursor(); + QAD_WaitCursor wc; + try{ + SALOMEDS::SObject_var aSobj = myStudyAPI.FindObject(theMesh); + CORBA::String_var anEntry = aSobj->GetID(); + if(SMESH_Actor* anActor = ::FindActorByEntry(anEntry.in())){ + SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array; + anArrayOfIdeces->length(MapIndex.Extent()); + TColStd_MapIteratorOfMapOfInteger ite(MapIndex); + for(int i = 0; ite.More(); ite.Next(), i++){ + anArrayOfIdeces[i] = anActor->GetNodeObjId(ite.Key()); + } + SMESH::SMESH_MeshEditor_var aMeshEditor = theMesh->GetMeshEditor(); + aMeshEditor->AddVolume(anArrayOfIdeces); + if(myAutomaticUpdate){ + CORBA::Long anId = smeshGUI->myStudy->StudyId(); + if(TVisualObjPtr aVisualObj = GetVisualObj(anId,anEntry.in())){ + aVisualObj->Update(true); + } + } + } + }catch(SALOME::SALOME_Exception& exc) { + INFOS("Follow exception was cought:\n\t"<length(MapIndex.Extent()); - - int i = 0; - for (; ite.More(); ite.Next()) - { - anArrayOfIdeces[i] = ac->GetIdSMESHDSNode(ite.Key()); - i++; - } - - SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor(); - aMeshEditor->AddEdge(anArrayOfIdeces); - } - if (myAutomaticUpdate) - { - SMESH_Actor *Mesh = smeshGUI->ReadScript(aMesh); - if (Mesh != NULL) - { - smeshGUI->DisplayActor(Mesh); - smeshGUI->DisplayEdges(Mesh); - smeshGUI->ChangeRepresentation(Mesh, Mesh->getDisplayMode()); - AddActorInSelection(Mesh); - } - } - QApplication::restoreOverrideCursor(); + QAD_WaitCursor wc; + try{ + SALOMEDS::SObject_var aSobj = myStudyAPI.FindObject(theMesh); + CORBA::String_var anEntry = aSobj->GetID(); + if(SMESH_Actor* anActor = ::FindActorByEntry(anEntry.in())){ + SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array; + anArrayOfIdeces->length(MapIndex.Extent()); + TColStd_MapIteratorOfMapOfInteger ite(MapIndex); + for(int i = 0; ite.More(); ite.Next(), i++){ + anArrayOfIdeces[i] = anActor->GetNodeObjId(ite.Key()); + } + SMESH::SMESH_MeshEditor_var aMeshEditor = theMesh->GetMeshEditor(); + aMeshEditor->AddEdge(anArrayOfIdeces); + if(myAutomaticUpdate){ + CORBA::Long anId = smeshGUI->myStudy->StudyId(); + if(TVisualObjPtr aVisualObj = GetVisualObj(anId,anEntry.in())){ + aVisualObj->Update(true); + } + } + } + }catch(SALOME::SALOME_Exception& exc) { + INFOS("Follow exception was cought:\n\t"<GetMeshEditor(); - aMeshEditor->AddNode(x, y, z); - - if (myAutomaticUpdate) - { - SMESH_Actor *Mesh = smeshGUI->ReadScript(aMesh); - if (Mesh != NULL) - { - smeshGUI->DisplayActor(Mesh); - smeshGUI->DisplayEdges(Mesh); - smeshGUI->ChangeRepresentation(Mesh, Mesh->getDisplayMode()); - AddActorInSelection(Mesh); - } - } - } - QApplication::restoreOverrideCursor(); + QAD_WaitCursor wc; + try{ + SALOMEDS::SObject_var aSobj = myStudyAPI.FindObject(theMesh); + CORBA::String_var anEntry = aSobj->GetID(); + if(SMESH_Actor* anActor = ::FindActorByEntry(anEntry.in())){ + SMESH::SMESH_MeshEditor_var aMeshEditor = theMesh->GetMeshEditor(); + aMeshEditor->AddNode(x, y, z); + if(myAutomaticUpdate){ + CORBA::Long anId = smeshGUI->myStudy->StudyId(); + if(TVisualObjPtr aVisualObj = GetVisualObj(anId,anEntry.in())){ + aVisualObj->Update(true); + } + } + } + }catch(SALOME::SALOME_Exception& exc) { + INFOS("Follow exception was cought:\n\t"<getStudyFramesCount(); - - Standard_Boolean found; - SALOMEDS::Study_var aStudy = myActiveStudy->getStudyDocument(); - SALOMEDS::StudyBuilder_var aStudyBuilder = myStudy->NewBuilder(); - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::AttributeIOR_var anIOR; - - SALOME_Selection *Sel = - SALOME_Selection::Selection(myActiveStudy->getSelection()); - SALOME_ListIteratorOfListIO It(Sel->StoredIObjects()); - for (; It.More(); It.Next()) - { - Handle(SALOME_InteractiveObject) IObject = It.Value(); - if (IObject->hasEntry()) - { - SALOMEDS::SObject_var SO = - myStudy->FindObjectID(IObject->getEntry()); - - /* Erase child graphical objects */ - SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator(SO); - for (; it->More(); it->Next()) - { - SALOMEDS::SObject_var CSO = it->Value(); - if (CSO->FindAttribute(anAttr, "AttributeIOR")) - { - anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - - for (int i = 0; i < nbSf; i++) - { - QAD_StudyFrame *sf = myActiveStudy->getStudyFrame(i); - if (sf->getTypeView() == VIEW_VTK) - { - vtkRenderer *Renderer = - ((VTKViewer_ViewFrame *) smeshGUI-> - myActiveStudy->getActiveStudyFrame()-> - getRightFrame()->getViewFrame())->getRenderer(); - SMESH_Actor *ac = - smeshGUI->FindActorByEntry(CSO->GetID(), found, - false); - if (found) - { - Renderer->RemoveActor(ac->EdgeDevice); - Renderer->RemoveActor(ac->EdgeShrinkDevice); - Renderer->RemoveActor(ac); - } - } - } - } - } - - /* Erase main graphical object */ - for (int i = 0; i < nbSf; i++) - { - QAD_StudyFrame *sf = myActiveStudy->getStudyFrame(i); - if (sf->getTypeView() == VIEW_VTK) - { - vtkRenderer *Renderer = - ((VTKViewer_ViewFrame *) smeshGUI->myActiveStudy-> - getActiveStudyFrame()->getRightFrame()-> - getViewFrame())->getRenderer(); - VTKViewer_RenderWindowInteractor *myRenderInter = - ((VTKViewer_ViewFrame *) sf->getRightFrame()-> - getViewFrame())->getRWInteractor(); - SMESH_Actor *ac = - smeshGUI->FindActorByEntry(IObject->getEntry(), found, - false); - if (found) - { - Renderer->RemoveActor(ac->EdgeDevice); - Renderer->RemoveActor(ac->EdgeShrinkDevice); - } - myRenderInter->Remove(IObject); - } - } - - /* Erase objects in Study */ - SALOMEDS::SObject_var obj = - myStudy->FindObjectID(IObject->getEntry()); - if (!obj->_is_nil()) - { - QAD_Operation *op = - new SALOMEGUI_ImportOperation(myActiveStudy); - op->start(); - aStudyBuilder->RemoveObject(obj); - op->finish(); - } - - } /* IObject->hasEntry() */ - } /* more/next */ + if (QAD_MessageBox::warn2 + (QAD_Application::getDesktop(), + tr("SMESH_WRN_WARNING"), + tr("SMESH_REALLY_DELETE"), + tr("SMESH_BUT_YES"), tr("SMESH_BUT_NO"), 1, 0, 0) != 1) + return; + + int nbSf = myActiveStudy->getStudyFramesCount(); + + Standard_Boolean found; + SALOMEDS::Study_var aStudy = myActiveStudy->getStudyDocument(); + SALOMEDS::StudyBuilder_var aStudyBuilder = myStudy->NewBuilder(); + SALOMEDS::GenericAttribute_var anAttr; + SALOMEDS::AttributeIOR_var anIOR; + + SALOME_Selection *Sel = SALOME_Selection::Selection(myActiveStudy->getSelection()); + SALOME_ListIteratorOfListIO It(Sel->StoredIObjects()); + for(; It.More(); It.Next()){ + Handle(SALOME_InteractiveObject) IObject = It.Value(); + if(IObject->hasEntry()){ + SALOMEDS::SObject_var SO = myStudy->FindObjectID(IObject->getEntry()); + + /* Erase child graphical objects */ + SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator(SO); + for(; it->More(); it->Next()){ + SALOMEDS::SObject_var CSO = it->Value(); + if(CSO->FindAttribute(anAttr, "AttributeIOR")){ + anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + + for(int i = 0; i < nbSf; i++){ + QAD_StudyFrame *sf = myActiveStudy->getStudyFrame(i); + CORBA::String_var anEntry = CSO->GetID(); + if(SMESH_Actor* anActor = ::FindActorByEntry(sf,anEntry.in())){ + RemoveActor(sf,anActor); + } + } + } + } + + /* Erase main graphical object */ + for(int i = 0; i < nbSf; i++){ + QAD_StudyFrame *sf = myActiveStudy->getStudyFrame(i); + if(SMESH_Actor* anActor = ::FindActorByEntry(sf,IObject->getEntry())){ + RemoveActor(sf,anActor); + } + } + + // Remove object(s) from data structures + SALOMEDS::SObject_var obj = myStudy->FindObjectID(IObject->getEntry()); + if(!obj->_is_nil()){ + SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group ::_narrow(obj->GetObject()); + SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(obj->GetObject()); + + if ( !aGroup->_is_nil() ) { // DELETE GROUP + SMESH::SMESH_Mesh_var aMesh = aGroup->GetMesh(); + aMesh->RemoveGroup( aGroup ); + } + else if ( !aSubMesh->_is_nil() ) { // DELETE SUBMESH + SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather(); + aMesh->RemoveSubMesh( aSubMesh ); + } + else {// default action: remove SObject from the study + // san - it's no use opening a transaction here until UNDO/REDO is provided in SMESH + //QAD_Operation *op = new SALOMEGUI_ImportOperation(myActiveStudy); + //op->start(); + aStudyBuilder->RemoveObjectWithChildren( obj ); + //op->finish(); + } + } + + } /* IObject->hasEntry() */ + } /* more/next */ + + /* Clear any previous selection */ + Sel->ClearIObjects(); + myActiveStudy->updateObjBrowser(); +} - /* Clear any previous selection */ - Sel->ClearIObjects(); - myActiveStudy->updateObjBrowser(); +//======================================================================= +// name : SMESHGUI::GetFilterMgr +// Purpose : Get filter manager +//======================================================================= +SMESH::FilterManager_ptr SMESHGUI::GetFilterMgr() +{ + return myFilterMgr; } diff --git a/src/SMESHGUI/SMESHGUI.h b/src/SMESHGUI/SMESHGUI.h index fdcbe7cda..4c17a2cb6 100644 --- a/src/SMESHGUI/SMESHGUI.h +++ b/src/SMESHGUI/SMESHGUI.h @@ -30,38 +30,46 @@ #define SMESHGUI_HeaderFile #include "TColStd_MapOfInteger.hxx" +#include #include "SMESHDS_Document.hxx" // SALOME Includes +#include "SALOMEGUI.h" #include "QAD_Desktop.h" #include "SALOME_Selection.h" #include "SALOME_InteractiveObject.hxx" -#include "SMESH_Actor.h" - #include "SMESHGUI_StudyAPI.h" +#include "SMESHGUI_Hypotheses.h" // IDL Headers #include #include CORBA_SERVER_HEADER(SMESH_Gen) #include CORBA_SERVER_HEADER(SMESH_Mesh) +#include CORBA_SERVER_HEADER(SMESH_Group) #include CORBA_SERVER_HEADER(SMESH_Hypothesis) -#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) #include CORBA_SERVER_HEADER(GEOM_Gen) #include CORBA_SERVER_HEADER(SALOMEDS_Attributes) +#include CORBA_SERVER_HEADER(SMESH_Filter) // QT Includes #include -// VTK Inlcudes -#include +// VTK Inlcludes + +class vtkActorCollection; +class vtkActor2DCollection; +class vtkScalarBarActor; +class vtkActor; + +class SMESH_Actor; //================================================================================= // class : SMESHGUI // purpose : //================================================================================= -class SMESHGUI : public QObject +class SMESHGUI : public SALOMEGUI { Q_OBJECT @@ -88,11 +96,20 @@ private : // vtkScalarBarActor* myScalarBar; + SMESHDS_Document * myDocument;//NBU + bool myAutomaticUpdate; + SMESH::FilterManager_var myFilterMgr; + + // Hypotheses/algorithms from plugin libraries + map myHypothesesMap; + map myAlgorithmsMap; + map myHypCreatorMap; + public : - SMESHGUI(); + SMESHGUI( const QString& name = "", QObject* parent = 0 ); ~SMESHGUI(); static SMESHGUI* GetOrCreateSMESHGUI( QAD_Desktop* desktop ); @@ -103,8 +120,6 @@ public : SALOMEDS::Study_ptr GetStudy(); SMESHGUI_StudyAPI GetStudyAPI(); - vtkScalarBarActor* GetScalarBar(); - QDialog* GetActiveDialogBox() ; void SetActiveDialogBox(QDialog* aDlg) ; @@ -113,104 +128,75 @@ public : bool DefineDlgPosition(QWidget* aDlg, int& x, int& y) ; - /* Managed by IAPP */ - Standard_EXPORT static bool OnGUIEvent ( int theCommandID, QAD_Desktop* parent) ; - Standard_EXPORT static bool OnMousePress ( QMouseEvent* pe, QAD_Desktop* parent, - QAD_StudyFrame* studyFrame ); - Standard_EXPORT static bool OnMouseMove ( QMouseEvent* pe, QAD_Desktop* parent, - QAD_StudyFrame* studyFrame ); - Standard_EXPORT static bool OnKeyPress ( QKeyEvent* pe, QAD_Desktop* parent, - QAD_StudyFrame* studyFrame ); - Standard_EXPORT static void activeStudyChanged ( QAD_Desktop* parent ); - Standard_EXPORT static bool SetSettings ( QAD_Desktop* parent ); - Standard_EXPORT static void DefinePopup( QString & theContext, - QString & theParent, - QString & theObject ); - Standard_EXPORT static bool CustomPopup ( QAD_Desktop* parent, - QPopupMenu* popup, - const QString& theContext, - const QString& theParent, - const QString& theObject ); - Standard_EXPORT static void BuildPresentation(const Handle(SALOME_InteractiveObject)&); + virtual bool OnGUIEvent (int theCommandID, QAD_Desktop* parent); + virtual bool OnMousePress (QMouseEvent* pe, QAD_Desktop* parent, QAD_StudyFrame* studyFrame); + virtual bool OnMouseMove (QMouseEvent* pe, QAD_Desktop* parent, QAD_StudyFrame* studyFrame); + virtual bool OnKeyPress (QKeyEvent* pe, QAD_Desktop* parent, QAD_StudyFrame* studyFrame); + virtual bool ActiveStudyChanged( QAD_Desktop* parent ); + virtual bool SetSettings ( QAD_Desktop* parent ); + virtual void DefinePopup ( QString & theContext, QString & theParent, QString & theObject ); + virtual bool CustomPopup ( QAD_Desktop* parent, QPopupMenu* popup, const QString & theContext, + const QString & theParent, const QString & theObject ); + virtual void BuildPresentation ( const Handle(SALOME_InteractiveObject)& theIO ); + virtual void SupportedViewType (int* buffer, int bufferSize); + virtual void Deactivate (); void OnEditDelete(); /* Mesh Management */ SMESH::SMESH_Mesh_ptr InitMesh( GEOM::GEOM_Shape_ptr aShape, QString NameMesh ); SMESH::SMESH_subMesh_ptr AddSubMesh( SMESH::SMESH_Mesh_ptr aMesh, GEOM::GEOM_Shape_ptr aShape, QString NameMesh ); + SMESH::SMESH_Group_ptr AddGroup( SMESH::SMESH_Mesh_ptr aMesh, SMESH::ElementType aType, QString aName ); + + /* Hypotheses and Algorithms Management */ + void InitAvailableHypotheses (); + QStringList GetAvailableHypotheses (const bool isAlgo); + HypothesisData* GetHypothesisData (const char* aHypType); + SMESHGUI_GenericHypothesisCreator* GetHypothesisCreator (const QString& aHypType); + + SMESH::SMESH_Hypothesis_ptr CreateHypothesis (const QString& aHypType, + const QString& aHypName, + const bool isAlgo = false); - /* Hypothesis Management */ - SMESH::SMESH_Hypothesis_ptr CreateHypothesis( QString TypeHypothesis, QString NameHypothesis ); - void AddHypothesisOnMesh( SMESH::SMESH_Mesh_ptr aMesh, SMESH::SMESH_Hypothesis_ptr aHyp ) ; - void AddHypothesisOnSubMesh( SMESH::SMESH_subMesh_ptr aSubMesh, SMESH::SMESH_Hypothesis_ptr aHyp ) ; + bool AddHypothesisOnMesh (SMESH::SMESH_Mesh_ptr aMesh, SMESH::SMESH_Hypothesis_ptr aHyp); + bool AddAlgorithmOnMesh (SMESH::SMESH_Mesh_ptr aMesh, SMESH::SMESH_Hypothesis_ptr aHyp); - void RemoveHypothesisOrAlgorithmOnMesh( const Handle(SALOME_InteractiveObject)& IObject ) ; - void RemoveHypothesisOrAlgorithmOnMesh( SALOMEDS::SObject_ptr MorSM, SMESH::SMESH_Hypothesis_ptr anHyp ) ; + bool AddHypothesisOnSubMesh (SMESH::SMESH_subMesh_ptr aSubMesh, SMESH::SMESH_Hypothesis_ptr aHyp); + bool AddAlgorithmOnSubMesh (SMESH::SMESH_subMesh_ptr aSubMesh, SMESH::SMESH_Hypothesis_ptr aHyp); - void CreateLocalLength( QString TypeHypothesis, QString NameHypothesis, double Length ); - void CreateNbSegments( QString TypeHypothesis, QString NameHypothesis, int nbSegments ); - void CreateMaxElementArea( QString TypeHypothesis, QString NameHypothesis, double MaxArea ); - void CreateMaxElementVolume( QString TypeHypothesis, QString NameHypothesis, double MaxVolume ); + bool RemoveHypothesisOrAlgorithmOnMesh (const Handle(SALOME_InteractiveObject)& IObject); + bool RemoveHypothesisOrAlgorithmOnMesh (SALOMEDS::SObject_ptr MorSM, + SMESH::SMESH_Hypothesis_ptr anHyp); - /* Algorithms Management */ - void AddAlgorithmOnMesh( SMESH::SMESH_Mesh_ptr aMesh, SMESH::SMESH_Hypothesis_ptr aHyp ); - void AddAlgorithmOnSubMesh( SMESH::SMESH_subMesh_ptr aSubMesh, SMESH::SMESH_Hypothesis_ptr aHyp ); - void CreateAlgorithm( QString TypeAlgo, QString NameAlgo ); + void SetPickable(SMESH_Actor* theActor = NULL); /* NODES */ void ViewNodes(); vtkActor* SimulationMoveNode(SMESH_Actor* Mactor, int idnode); void MoveNode( SMESH::SMESH_Mesh_ptr aMesh, int idnode, float x, float y, float z); - void AddNode(SMESH_Actor*, int idnode, float x, float y, float z) ; - void AddNodes( SMESH_Actor* Mactor, int number, - const SMESH::double_array& coords, const SMESH::long_array& indexes); void DisplaySimulationNode( SMESH::SMESH_Mesh_ptr aMesh, float x, float y, float z); void DisplaySimulationMoveNode( vtkActor* ac, int idnode, float x, float y, float z); - void RemoveNode(SMESH_Actor*, int idnode) ; void RemoveNodes(SMESH::SMESH_Mesh_ptr aMesh, const TColStd_MapOfInteger& MapIndex) ; - void RemoveNodes(SMESH_Actor* Mactor, int number, - const SMESH::double_array& coords, const SMESH::long_array& indexes); /* EDGES */ - void AddEdge(SMESH_Actor*, int idedge, int idnode1, int idnode2) ; - void AddEdges( SMESH_Actor* Mactor, int number, - const SMESH::double_array& coords, const SMESH::long_array& indexes); void DisplayEdges(SMESH_Actor* ac, bool visibility = true); void DisplayEdgesConnectivityLegendBox(vtkActor *ac); void DisplaySimulationEdge( SMESH::SMESH_Mesh_ptr aMesh, const TColStd_MapOfInteger& MapIndex ); /* TRIANGLES */ - void AddTriangle(SMESH_Actor*, int idtri, int idnode1, int idnode2, int idnode3) ; - void AddTriangles( SMESH_Actor* Mactor, int number, - const SMESH::double_array& coords, const SMESH::long_array& indexes); void DisplaySimulationTriangle( SMESH::SMESH_Mesh_ptr aMesh, const TColStd_MapOfInteger& MapIndex, bool reverse ); /* QUADRANGLES */ - void AddQuadrangle(SMESH_Actor*, int idquad, int idnode1, int idnode2, - int idnode3, int idnode4) ; - void AddQuadrangles( SMESH_Actor* Mactor, int number, - const SMESH::double_array& coords, const SMESH::long_array& indexes); void DisplaySimulationQuadrangle( SMESH::SMESH_Mesh_ptr aMesh, const TColStd_MapOfInteger& MapIndex, bool reverse ); /* VOLUMES */ - void AddTetra(SMESH_Actor*, int idtetra, int idnode1, int idnode2, - int idnode3, int idnode4) ; - void AddHexaedre(SMESH_Actor*, int idhexa, int idnode1, int idnode2, - int idnode3, int idnode4, int idnode5, int idnode6, int idnode7, int idnode8) ; - void AddTetras( SMESH_Actor* Mactor, int number, - const SMESH::double_array& coords, const SMESH::long_array& indexes); - void AddHexaedres( SMESH_Actor* Mactor, int number, - const SMESH::double_array& coords, const SMESH::long_array& indexes); void DisplaySimulationTetra( SMESH::SMESH_Mesh_ptr aMesh, const TColStd_MapOfInteger& MapIndex ); void DisplaySimulationHexa( SMESH::SMESH_Mesh_ptr aMesh, const TColStd_MapOfInteger& MapIndex ); /* ELEMENTS */ - void RemoveElement(SMESH_Actor*, int idnode); void RemoveElements(SMESH::SMESH_Mesh_ptr aMesh, const TColStd_MapOfInteger& MapIndex) ; - void RemoveElements(SMESH_Actor* Mactor, int number, - const SMESH::double_array& coords, const SMESH::long_array& indexes); void OrientationElements(SMESH::SMESH_Mesh_ptr aMesh, const TColStd_MapOfInteger& MapIndex); void DiagonalInversion(SMESH::SMESH_Mesh_ptr aMesh, const TColStd_MapOfInteger& MapIndex); @@ -237,6 +223,7 @@ public : SMESH::SMESH_Mesh_ptr ConvertIOinMesh(const Handle(SALOME_InteractiveObject)& IO, Standard_Boolean& testResult) ; SMESH::SMESH_subMesh_ptr ConvertIOinSubMesh(const Handle(SALOME_InteractiveObject)& IO, Standard_Boolean& testResult) ; + SMESH::SMESH_Group_ptr ConvertIOinSMESHGroup(const Handle(SALOME_InteractiveObject)& IO, Standard_Boolean& testResult) ; /* Geometry Client */ GEOM::GEOM_Shape_ptr ConvertIOinGEOMShape( const Handle(SALOME_InteractiveObject)& IO, @@ -255,7 +242,7 @@ public : void SetViewMode(int commandId); void ChangeRepresentation( SMESH_Actor* ac, int type ); - SMESH_Actor* FindActor(SMESH::SMESH_Mesh_ptr aMesh, + SMESH_Actor* FindActor(CORBA::Object_ptr theObj, Standard_Boolean& testResult, bool onlyInActiveView); SMESH_Actor* FindActorByEntry(QString entry, @@ -280,10 +267,7 @@ public : QString Bold, QString Italic, QString Shadow, QString Font, QString Orientation, float Width, float Height, int NbColors, int NbLabels); - void DisplayScalarBar(bool visibility); - void UpdateScalarBar(float MinRange, float MaxRange); - - void SetDisplaySettings(); + void SetDisplaySettings(); SALOMEDS::Study::ListOfSObject* GetMeshesUsingAlgoOrHypothesis( SMESH::SMESH_Hypothesis_ptr AlgoOrHyp ) ; @@ -301,9 +285,12 @@ public : static void setOrb(); /* Import/Export */ //NBU - void Import_Document(QAD_Desktop* parent, int theCommandID); + static void Import_Mesh(QAD_Desktop* parent, int theCommandID); static void Export_Mesh(QAD_Desktop* parent, int theCommandID); + /* Filter manager */ + SMESH::FilterManager_ptr GetFilterMgr(); + signals: void SignalDeactivateActiveDialog() ; void SignalCloseAllDialogs() ; diff --git a/src/SMESHGUI/SMESHGUI_AddEdgeDlg.cxx b/src/SMESHGUI/SMESHGUI_AddEdgeDlg.cxx index 8fe1cc201..2b40287d0 100644 --- a/src/SMESHGUI/SMESHGUI_AddEdgeDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_AddEdgeDlg.cxx @@ -255,7 +255,7 @@ void SMESHGUI_AddEdgeDlg::ClickOnOk() //================================================================================= void SMESHGUI_AddEdgeDlg::ClickOnCancel() { - QAD_Application::getDesktop()->SetSelectionMode( 4 ); + QAD_Application::getDesktop()->SetSelectionMode( ActorSelection ); disconnect( mySelection, 0, this, 0 ); mySMESHGUI->ResetState() ; mySMESHGUI->EraseSimulationActors(); @@ -282,9 +282,9 @@ void SMESHGUI_AddEdgeDlg::SelectionIntoArgument() if(nbNodes < 1) return ; - if ( mySelection->SelectionMode() != 1 ) { + if ( mySelection->SelectionMode() != NodeSelection ) { QAD_MessageBox::warn1 ( QAD_Application::getDesktop(), tr ("SMESH_WRN_WARNING"), - tr ("SMESH_WRN_SELECTIONMODE_NODES"), tr ("SMESH_BUT_YES") ); + tr ("SMESH_WRN_SELECTIONMODE_NODES"), tr ("SMESH_BUT_OK") ); return; } diff --git a/src/SMESHGUI/SMESHGUI_AddFaceDlg.cxx b/src/SMESHGUI/SMESHGUI_AddFaceDlg.cxx index 168dc1350..b294f9368 100644 --- a/src/SMESHGUI/SMESHGUI_AddFaceDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_AddFaceDlg.cxx @@ -278,7 +278,7 @@ void SMESHGUI_AddFaceDlg::ClickOnOk() //================================================================================= void SMESHGUI_AddFaceDlg::ClickOnCancel() { - QAD_Application::getDesktop()->SetSelectionMode( 4 ); + QAD_Application::getDesktop()->SetSelectionMode( ActorSelection ); disconnect( mySelection, 0, this, 0 ); mySMESHGUI->ResetState() ; mySMESHGUI->EraseSimulationActors(); @@ -305,9 +305,9 @@ void SMESHGUI_AddFaceDlg::SelectionIntoArgument() if(nbNodes < 1) return ; - if ( mySelection->SelectionMode() != 1 ) { + if ( mySelection->SelectionMode() != NodeSelection ) { QAD_MessageBox::warn1 ( QAD_Application::getDesktop(), tr ("SMESH_WRN_WARNING"), - tr ("SMESH_WRN_SELECTIONMODE_NODES"), tr ("SMESH_BUT_YES") ); + tr ("SMESH_WRN_SELECTIONMODE_NODES"), tr ("SMESH_BUT_OK") ); return; } diff --git a/src/SMESHGUI/SMESHGUI_AddSubMeshDlg.cxx b/src/SMESHGUI/SMESHGUI_AddSubMeshDlg.cxx index 91ec96dee..b3ab63dfc 100644 --- a/src/SMESHGUI/SMESHGUI_AddSubMeshDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_AddSubMeshDlg.cxx @@ -33,23 +33,20 @@ using namespace std; #include "QAD_Application.h" #include "QAD_Desktop.h" +#include "QAD_MessageBox.h" +#include "QAD_WaitCursor.h" +#include "QAD_Operation.h" + #include "utilities.h" // QT Includes -#include #include #include #include #include -#include #include -#include -#include -#include -#include #include - //================================================================================= // class : SMESHGUI_AddSubMeshDlg() // purpose : Constructs a SMESHGUI_AddSubMeshDlg which is a child of 'parent', with the @@ -58,149 +55,97 @@ using namespace std; // TRUE to construct a modal dialog. //================================================================================= SMESHGUI_AddSubMeshDlg::SMESHGUI_AddSubMeshDlg( QWidget* parent, const char* name, SALOME_Selection* Sel, bool modal, WFlags fl ) - : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ) + : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose ) { - QPixmap image1(QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr("ICON_DLG_ADD_SUBMESH"))); QPixmap image0(QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr("ICON_SELECT"))); if ( !name ) setName( "SMESHGUI_AddSubMeshDlg" ); - resize( 303, 175 ); setCaption( tr( "SMESH_ADD_SUBMESH" ) ); setSizeGripEnabled( TRUE ); - SMESHGUI_AddSubMeshDlgLayout = new QGridLayout( this ); + QGridLayout* SMESHGUI_AddSubMeshDlgLayout = new QGridLayout( this ); SMESHGUI_AddSubMeshDlgLayout->setSpacing( 6 ); SMESHGUI_AddSubMeshDlgLayout->setMargin( 11 ); /***************************************************************/ - GroupConstructors = new QButtonGroup( this, "GroupConstructors" ); - GroupConstructors->setTitle( tr( "SMESH_SUBMESH" ) ); - GroupConstructors->setExclusive( TRUE ); - GroupConstructors->setColumnLayout(0, Qt::Vertical ); - GroupConstructors->layout()->setSpacing( 0 ); - GroupConstructors->layout()->setMargin( 0 ); - GroupConstructorsLayout = new QGridLayout( GroupConstructors->layout() ); - GroupConstructorsLayout->setAlignment( Qt::AlignTop ); - GroupConstructorsLayout->setSpacing( 6 ); - GroupConstructorsLayout->setMargin( 11 ); - Constructor1 = new QRadioButton( GroupConstructors, "Constructor1" ); - Constructor1->setText( tr( "" ) ); - Constructor1->setPixmap( image1 ); - Constructor1->setChecked( TRUE ); - Constructor1->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, Constructor1->sizePolicy().hasHeightForWidth() ) ); - Constructor1->setMinimumSize( QSize( 50, 0 ) ); - GroupConstructorsLayout->addWidget( Constructor1, 0, 0 ); - QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); - GroupConstructorsLayout->addItem( spacer, 0, 1 ); - SMESHGUI_AddSubMeshDlgLayout->addWidget( GroupConstructors, 0, 0 ); - - /***************************************************************/ - GroupButtons = new QGroupBox( this, "GroupButtons" ); - GroupButtons->setGeometry( QRect( 10, 10, 281, 48 ) ); - GroupButtons->setTitle( tr( "" ) ); - GroupButtons->setColumnLayout(0, Qt::Vertical ); - GroupButtons->layout()->setSpacing( 0 ); - GroupButtons->layout()->setMargin( 0 ); - GroupButtonsLayout = new QGridLayout( GroupButtons->layout() ); - GroupButtonsLayout->setAlignment( Qt::AlignTop ); - GroupButtonsLayout->setSpacing( 6 ); - GroupButtonsLayout->setMargin( 11 ); - buttonCancel = new QPushButton( GroupButtons, "buttonCancel" ); - buttonCancel->setText( tr( "SMESH_BUT_CLOSE" ) ); - buttonCancel->setAutoDefault( TRUE ); - GroupButtonsLayout->addWidget( buttonCancel, 0, 3 ); - buttonApply = new QPushButton( GroupButtons, "buttonApply" ); - buttonApply->setText( tr( "SMESH_BUT_APPLY" ) ); - buttonApply->setAutoDefault( TRUE ); - GroupButtonsLayout->addWidget( buttonApply, 0, 1 ); - QSpacerItem* spacer_9 = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); - GroupButtonsLayout->addItem( spacer_9, 0, 2 ); - buttonOk = new QPushButton( GroupButtons, "buttonOk" ); - buttonOk->setText( tr( "SMESH_BUT_OK" ) ); - buttonOk->setAutoDefault( TRUE ); - buttonOk->setDefault( TRUE ); - GroupButtonsLayout->addWidget( buttonOk, 0, 0 ); - SMESHGUI_AddSubMeshDlgLayout->addWidget( GroupButtons, 2, 0 ); - - /***************************************************************/ - GroupC1 = new QGroupBox( this, "GroupC1" ); - GroupC1->setTitle( tr( "SMESH_ARGUMENTS" ) ); - GroupC1->setMinimumSize( QSize( 0, 0 ) ); - GroupC1->setFrameShape( QGroupBox::Box ); - GroupC1->setFrameShadow( QGroupBox::Sunken ); + GroupC1 = new QGroupBox( tr( "SMESH_ARGUMENTS" ), this, "GroupC1" ); GroupC1->setColumnLayout(0, Qt::Vertical ); GroupC1->layout()->setSpacing( 0 ); GroupC1->layout()->setMargin( 0 ); - GroupC1Layout = new QGridLayout( GroupC1->layout() ); + QGridLayout* GroupC1Layout = new QGridLayout( GroupC1->layout() ); GroupC1Layout->setAlignment( Qt::AlignTop ); GroupC1Layout->setSpacing( 6 ); GroupC1Layout->setMargin( 11 ); - TextLabelC1A1 = new QLabel( GroupC1, "TextLabelC1A1" ); - TextLabelC1A1->setText( tr( "SMESH_OBJECT_MESH" ) ); - TextLabelC1A1->setMinimumSize( QSize( 50, 0 ) ); - TextLabelC1A1->setFrameShape( QLabel::NoFrame ); - TextLabelC1A1->setFrameShadow( QLabel::Plain ); - GroupC1Layout->addWidget( TextLabelC1A1, 0, 0 ); + TextLabel_NameMesh = new QLabel( tr( "SMESH_NAME" ), GroupC1, "TextLabel_NameMesh" ); + GroupC1Layout->addWidget( TextLabel_NameMesh, 0, 0 ); + LineEdit_NameMesh = new QLineEdit( GroupC1, "LineEdit_NameMesh" ); + GroupC1Layout->addWidget( LineEdit_NameMesh, 0, 2 ); + + TextLabelC1A1 = new QLabel( tr( "SMESH_OBJECT_MESH" ), GroupC1, "TextLabelC1A1" ); + GroupC1Layout->addWidget( TextLabelC1A1, 1, 0 ); SelectButtonC1A1 = new QPushButton( GroupC1, "SelectButtonC1A1" ); - SelectButtonC1A1->setText( tr( "" ) ); SelectButtonC1A1->setPixmap( image0 ); SelectButtonC1A1->setToggleButton( FALSE ); - GroupC1Layout->addWidget( SelectButtonC1A1, 0, 1 ); + GroupC1Layout->addWidget( SelectButtonC1A1, 1, 1 ); LineEditC1A1 = new QLineEdit( GroupC1, "LineEditC1A1" ); - GroupC1Layout->addWidget( LineEditC1A1, 0, 2 ); - - TextLabelC1A2 = new QLabel( GroupC1, "TextLabelC1A2" ); - TextLabelC1A2->setText( tr( "SMESH_OBJECT_GEOM" ) ); - TextLabelC1A2->setMinimumSize( QSize( 50, 0 ) ); - TextLabelC1A2->setFrameShape( QLabel::NoFrame ); - TextLabelC1A2->setFrameShadow( QLabel::Plain ); - GroupC1Layout->addWidget( TextLabelC1A2, 1, 0 ); + GroupC1Layout->addWidget( LineEditC1A1, 1, 2 ); + + TextLabelC1A2 = new QLabel( tr( "SMESH_OBJECT_GEOM" ), GroupC1, "TextLabelC1A2" ); + GroupC1Layout->addWidget( TextLabelC1A2, 2, 0 ); SelectButtonC1A2 = new QPushButton( GroupC1, "SelectButtonC1A2" ); - SelectButtonC1A2->setText( tr( "" ) ); SelectButtonC1A2->setPixmap( image0 ); SelectButtonC1A2->setToggleButton( FALSE ); - GroupC1Layout->addWidget( SelectButtonC1A2, 1, 1 ); + GroupC1Layout->addWidget( SelectButtonC1A2, 2, 1 ); LineEditC1A2 = new QLineEdit( GroupC1, "LineEditC1A2" ); - GroupC1Layout->addWidget( LineEditC1A2, 1, 2 ); - - TextLabel_NameMesh = new QLabel( GroupC1, "TextLabel_NameMesh" ); - TextLabel_NameMesh->setText( tr( "SMESH_NAME" ) ); - GroupC1Layout->addWidget( TextLabel_NameMesh, 2, 0 ); - LineEdit_NameMesh = new QLineEdit( GroupC1, "LineEdit_NameMesh" ); - GroupC1Layout->addWidget( LineEdit_NameMesh, 2, 2 ); + GroupC1Layout->addWidget( LineEditC1A2, 2, 2 ); - TextLabelC1A1Hyp = new QLabel( GroupC1, "TextLabelC1A1Hyp" ); - TextLabelC1A1Hyp->setText( tr( "SMESH_OBJECT_HYPOTHESIS" ) ); - TextLabelC1A1Hyp->setMinimumSize( QSize( 50, 0 ) ); - TextLabelC1A1Hyp->setFrameShape( QLabel::NoFrame ); - TextLabelC1A1Hyp->setFrameShadow( QLabel::Plain ); + TextLabelC1A1Hyp = new QLabel( tr( "SMESH_OBJECT_HYPOTHESIS" ), GroupC1, "TextLabelC1A1Hyp" ); GroupC1Layout->addWidget( TextLabelC1A1Hyp, 3, 0 ); SelectButtonC1A1Hyp = new QPushButton( GroupC1, "SelectButtonC1A1Hyp" ); - SelectButtonC1A1Hyp->setText( tr( "" ) ); SelectButtonC1A1Hyp->setPixmap( image0 ); GroupC1Layout->addWidget( SelectButtonC1A1Hyp, 3, 1 ); LineEditC1A1Hyp = new QLineEdit( GroupC1, "LineEditC1A1Hyp" ); - LineEditC1A1Hyp->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)3, (QSizePolicy::SizeType)0, LineEditC1A1Hyp->sizePolicy().hasHeightForWidth() ) ); GroupC1Layout->addWidget( LineEditC1A1Hyp, 3, 2 ); - TextLabelC1A1Algo = new QLabel( GroupC1, "TextLabelC1A1Algo" ); - TextLabelC1A1Algo->setText( tr( "SMESH_OBJECT_ALGORITHM" ) ); - TextLabelC1A1Algo->setMinimumSize( QSize( 50, 0 ) ); - TextLabelC1A1Algo->setFrameShape( QLabel::NoFrame ); - TextLabelC1A1Algo->setFrameShadow( QLabel::Plain ); + TextLabelC1A1Algo = new QLabel( tr( "SMESH_OBJECT_ALGORITHM" ), GroupC1, "TextLabelC1A1Algo" ); GroupC1Layout->addWidget( TextLabelC1A1Algo, 4, 0 ); SelectButtonC1A1Algo = new QPushButton( GroupC1, "SelectButtonC1A1Algo" ); - SelectButtonC1A1Algo->setText( tr( "" ) ); SelectButtonC1A1Algo->setPixmap( image0 ); GroupC1Layout->addWidget( SelectButtonC1A1Algo, 4, 1 ); LineEditC1A1Algo = new QLineEdit( GroupC1, "LineEditC1A1Algo" ); - LineEditC1A1Algo->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)3, (QSizePolicy::SizeType)0, LineEditC1A1Algo->sizePolicy().hasHeightForWidth() ) ); GroupC1Layout->addWidget( LineEditC1A1Algo, 4, 2 ); SMESHGUI_AddSubMeshDlgLayout->addWidget( GroupC1, 1, 0 ); + /***************************************************************/ + GroupButtons = new QGroupBox( this, "GroupButtons" ); + GroupButtons->setColumnLayout(0, Qt::Vertical ); + GroupButtons->layout()->setSpacing( 0 ); + GroupButtons->layout()->setMargin( 0 ); + QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() ); + GroupButtonsLayout->setAlignment( Qt::AlignTop ); + GroupButtonsLayout->setSpacing( 6 ); + GroupButtonsLayout->setMargin( 11 ); - Init(Sel) ; + buttonOk = new QPushButton( tr( "SMESH_BUT_OK" ), GroupButtons, "buttonOk" ); + buttonOk->setAutoDefault( TRUE ); + buttonOk->setDefault( TRUE ); + GroupButtonsLayout->addWidget( buttonOk, 0, 0 ); + + buttonApply = new QPushButton( tr( "SMESH_BUT_APPLY" ), GroupButtons, "buttonApply" ); + buttonApply->setAutoDefault( TRUE ); + GroupButtonsLayout->addWidget( buttonApply, 0, 1 ); + + GroupButtonsLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 2 ); + + buttonCancel = new QPushButton( tr( "SMESH_BUT_CLOSE" ), GroupButtons, "buttonCancel" ); + buttonCancel->setAutoDefault( TRUE ); + GroupButtonsLayout->addWidget( buttonCancel, 0, 3 ); + + SMESHGUI_AddSubMeshDlgLayout->addWidget( GroupButtons, 2, 0 ); + + /***************************************************************/ + Init( Sel ) ; } @@ -220,60 +165,41 @@ SMESHGUI_AddSubMeshDlg::~SMESHGUI_AddSubMeshDlg() //================================================================================= void SMESHGUI_AddSubMeshDlg::Init( SALOME_Selection* Sel ) { - GroupC1->show(); - myConstructorId = 0 ; - Constructor1->setChecked( TRUE ); - myEditCurrentArgument = LineEditC1A1 ; mySelection = Sel; mySMESHGUI = SMESHGUI::GetSMESHGUI() ; mySMESHGUI->SetActiveDialogBox( (QDialog*)this ) ; - myGeomFilter = new SALOME_TypeFilter( "GEOM" ); - myMeshFilter = new SMESH_TypeFilter( MESH ); - - myAlgorithmFilter = new SMESH_TypeFilter( ALGORITHM ); + myGeomFilter = new SALOME_TypeFilter( "GEOM" ); + myMeshFilter = new SMESH_TypeFilter( MESH ); + myAlgorithmFilter = new SMESH_TypeFilter( ALGORITHM ); myHypothesisFilter = new SMESH_TypeFilter( HYPOTHESIS ); - myNameSubMesh = "SubMesh"; - - myGeomShape = GEOM::GEOM_Shape::_nil(); - myMesh = SMESH::SMESH_Mesh::_nil(); - /* signals and slots connections */ - connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) ); - connect( buttonApply, SIGNAL( clicked() ), this, SLOT(ClickOnApply() ) ); + connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) ); + connect( buttonApply, SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) ); connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) ) ; - connect( GroupConstructors, SIGNAL(clicked(int) ), SLOT( ConstructorsClicked(int) ) ); - - connect( SelectButtonC1A1, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ; - connect( SelectButtonC1A2, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ; - connect( LineEdit_NameMesh, SIGNAL (textChanged(const QString&) ), this, SLOT( TextChangedInLineEdit(const QString&) ) ) ; - connect( SelectButtonC1A1Hyp, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ; + connect( SelectButtonC1A1, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ; + connect( SelectButtonC1A2, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ; + connect( SelectButtonC1A1Hyp, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ; connect( SelectButtonC1A1Algo, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ; - connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) ); - connect( mySMESHGUI, SIGNAL ( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ; - connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) ) ; + connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) ); + connect( mySMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ; + connect( mySMESHGUI, SIGNAL( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) ) ; int x, y ; mySMESHGUI->DefineDlgPosition( this, x, y ) ; this->move( x, y ) ; this->show() ; - SelectionIntoArgument(); - - return ; -} - + LineEdit_NameMesh->setText( tr( "SMESH_SUBMESH" ) ); + LineEdit_NameMesh->setFocus() ; + myEditCurrentArgument = LineEditC1A1 ; + mySelection->ClearFilters() ; + mySelection->AddFilter( myMeshFilter ) ; -//================================================================================= -// function : ConstructorsClicked() -// purpose : Radio button management -//================================================================================= -void SMESHGUI_AddSubMeshDlg::ConstructorsClicked(int constructorId) -{ - return ; + SelectionIntoArgument(); } //================================================================================= @@ -282,50 +208,77 @@ void SMESHGUI_AddSubMeshDlg::ConstructorsClicked(int constructorId) //================================================================================= void SMESHGUI_AddSubMeshDlg::ClickOnOk() { - this->ClickOnApply() ; - this->ClickOnCancel() ; + if ( this->ClickOnApply() ) + this->ClickOnCancel() ; } //================================================================================= // function : ClickOnApply() // purpose : //================================================================================= -void SMESHGUI_AddSubMeshDlg::ClickOnApply() +bool SMESHGUI_AddSubMeshDlg::ClickOnApply() { - switch(myConstructorId) - { - case 0 : - { - if ( !myNameSubMesh.isEmpty() && !myNameSubMesh.isNull() && - !myGeomShape->_is_nil() && !myMesh->_is_nil()) { - mySubMesh = mySMESHGUI->AddSubMesh( myMesh, myGeomShape, myNameSubMesh ) ; - } - - if( myOkHypothesis && !mySubMesh->_is_nil() ) { - SALOME_ListIteratorOfListIO It( HypoList ); - for(;It.More();It.Next()) { - Handle(SALOME_InteractiveObject) IObject = It.Value(); - Standard_Boolean testResult; - myHypothesis = mySMESHGUI->ConvertIOinSMESHHypothesis(IObject, testResult) ; - if( testResult ) - mySMESHGUI->AddHypothesisOnSubMesh(mySubMesh, myHypothesis) ; + QString myNameSubMesh = LineEdit_NameMesh->text().stripWhiteSpace(); + if ( myNameSubMesh.isEmpty() ) { + QAD_MessageBox::warn1( this, tr( "SMESH_WRN_WARNING" ), tr( "SMESH_WRN_EMPTY_NAME" ), tr( "SMESH_BUT_OK" ) ); + return false; + } + + if ( myMesh->_is_nil() || myGeomShape->_is_nil() || ( !HypoList.count() && !AlgoList.count() ) ) + return false; + + SALOMEDS::SObject_var aMeshSO = mySMESHGUI->GetStudyAPI().FindObject( myMesh ); + GEOM::GEOM_Shape_var myMainShape = mySMESHGUI->GetStudyAPI().GetShapeOnMeshOrSubMesh( aMeshSO ); + if ( myMainShape->_is_nil() ) + return false; + + QAD_WaitCursor wc; + + QAD_Operation* op = new QAD_Operation( mySMESHGUI->GetActiveStudy() ); + + // start transaction + op->start(); + + // create submesh + SMESH::SMESH_subMesh_var aSubMesh = mySMESHGUI->AddSubMesh( myMesh, myGeomShape, myNameSubMesh ) ; + + if ( !aSubMesh->_is_nil() ) { + // assign hypotheses + for( int i = 0; i < HypoList.count(); i++ ) { + SALOMEDS::SObject_var aHypSO = mySMESHGUI->GetStudy()->FindObjectID( HypoList[i] ); + if ( !aHypSO->_is_nil() ) { + CORBA::Object_var anObject = aHypSO->GetObject(); + if ( !CORBA::is_nil( anObject ) ) { + SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( anObject ); + if ( !aHyp->_is_nil() ) + if ( !mySMESHGUI->AddHypothesisOnSubMesh( aSubMesh, aHyp ) ) { + // abort transaction + op->abort(); + return false; } } - - if( myOkAlgorithm && !mySubMesh->_is_nil() ) { - SALOME_ListIteratorOfListIO It( AlgoList ); - for(;It.More();It.Next()) { - Handle(SALOME_InteractiveObject) IObject = It.Value(); - Standard_Boolean testResult; - myAlgorithm = mySMESHGUI->ConvertIOinSMESHHypothesis(IObject, testResult) ; - if( testResult ) - mySMESHGUI->AddAlgorithmOnSubMesh(mySubMesh, myAlgorithm) ; + } + } + // assign algorithms + for( int i = 0; i < AlgoList.count(); i++ ) { + SALOMEDS::SObject_var aHypSO = mySMESHGUI->GetStudy()->FindObjectID( AlgoList[i] ); + if ( !aHypSO->_is_nil() ) { + CORBA::Object_var anObject = aHypSO->GetObject(); + if ( !CORBA::is_nil( anObject ) ) { + SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( anObject ); + if ( !aHyp->_is_nil() ) + if ( !mySMESHGUI->AddAlgorithmOnSubMesh( aSubMesh, aHyp ) ) { + // abort transaction + op->abort(); + return false; } } - - break ; } } + } + // commit transaction + op->finish(); + return true; } @@ -335,13 +288,20 @@ void SMESHGUI_AddSubMeshDlg::ClickOnApply() //================================================================================= void SMESHGUI_AddSubMeshDlg::ClickOnCancel() { - disconnect( mySelection, 0, this, 0 ); - mySMESHGUI->ResetState() ; - mySelection->ClearFilters() ; - reject() ; - return ; + close(); } +static bool IsFatherOf( SALOMEDS::SObject_ptr SO, SALOMEDS::SObject_ptr fatherSO ) { + if ( !SO->_is_nil() && !fatherSO->_is_nil() ) { + SALOMEDS::SObject_var aSO = SO->GetFather(); + while( strlen( aSO->GetID() ) >= strlen( fatherSO->GetID() ) ) { + if ( QString( aSO->GetID() ) == QString( fatherSO->GetID() ) ) + return true; + aSO = aSO->GetFather(); + } + } + return false; +} //================================================================================= // function : SelectionIntoArgument() @@ -349,81 +309,88 @@ void SMESHGUI_AddSubMeshDlg::ClickOnCancel() //================================================================================= void SMESHGUI_AddSubMeshDlg::SelectionIntoArgument() { - myEditCurrentArgument->setText("") ; + SMESHGUI_StudyAPI myStudyAPI = mySMESHGUI->GetStudyAPI(); QString aString = ""; int nbSel = mySMESHGUI->GetNameOfSelectedIObjects(mySelection, aString) ; - switch (myConstructorId) - { - case 0: - { - if ( myEditCurrentArgument == LineEditC1A1 ) { - if ( nbSel != 1 ) { - myOkHypothesis = false; - myOkAlgorithm = false; - return ; - } else { - Standard_Boolean testResult ; - Handle(SALOME_InteractiveObject) IO = mySelection->firstIObject() ; - myMesh = mySMESHGUI->ConvertIOinMesh(IO, testResult) ; - if( !testResult ) { - myMesh = SMESH::SMESH_Mesh::_nil(); - return ; - } - } - } else if ( myEditCurrentArgument == LineEditC1A2 ) { - if ( nbSel != 1 ) { - myOkHypothesis = false; - myOkAlgorithm = false; - return ; - } else { - Standard_Boolean testResult ; - Handle(SALOME_InteractiveObject) IO = mySelection->firstIObject() ; - myGeomShape = mySMESHGUI->ConvertIOinGEOMShape(IO, testResult) ; - if( !testResult ) { - myGeomShape = GEOM::GEOM_Shape::_nil(); - return ; - } - } - } else if ( myEditCurrentArgument == LineEditC1A1Hyp ) { - if ( nbSel >= 1 ) { - HypoList.Clear(); - SALOME_ListIteratorOfListIO Itinit( mySelection->StoredIObjects() ); - for (; Itinit.More(); Itinit.Next()) { - HypoList.Append(Itinit.Value()); - } - myOkHypothesis = true ; - if (nbSel > 1) - aString = tr("%1 Hypothesis").arg(nbSel) ; - LineEditC1A1Hyp->setText(aString) ; - } - else { - myOkHypothesis = false ; - return ; - } - } else if ( myEditCurrentArgument == LineEditC1A1Algo ) { - if ( nbSel >= 1 ) { - AlgoList.Clear(); - SALOME_ListIteratorOfListIO Itinit( mySelection->StoredIObjects() ); - for (; Itinit.More(); Itinit.Next()) { - AlgoList.Append(Itinit.Value()); - } - myOkAlgorithm = true ; - if (nbSel > 1) - aString = tr("%1 Algorithms").arg(nbSel) ; - LineEditC1A1Algo->setText(aString) ; - } - else { - myOkAlgorithm = false ; - return ; - } - } - break; + if ( myEditCurrentArgument == LineEditC1A1 ) { + // mesh + if ( nbSel != 1 ) { + myMesh = SMESH::SMESH_Mesh::_nil(); + aString = ""; + } + else { + Standard_Boolean testResult ; + Handle(SALOME_InteractiveObject) IO = mySelection->firstIObject() ; + myMesh = mySMESHGUI->ConvertIOinMesh(IO, testResult) ; + if( !testResult ) { + myMesh = SMESH::SMESH_Mesh::_nil(); + aString = ""; + } + } + myGeomShape = GEOM::GEOM_Shape::_nil(); + LineEditC1A2->setText( "" ); + } + else if ( myEditCurrentArgument == LineEditC1A2 ) { + // geom shape + if ( nbSel != 1 ) { + myGeomShape = GEOM::GEOM_Shape::_nil(); + aString = ""; + } + else { + Standard_Boolean testResult ; + Handle(SALOME_InteractiveObject) IO = mySelection->firstIObject() ; + myGeomShape = mySMESHGUI->ConvertIOinGEOMShape(IO, testResult) ; + if( !testResult ) { + myGeomShape = GEOM::GEOM_Shape::_nil(); + aString = ""; } + if ( !myMesh->_is_nil() ) { + SALOMEDS::SObject_var aMeshSO = myStudyAPI.FindObject( myMesh ); + GEOM::GEOM_Shape_var aMainGeomShape = myStudyAPI.GetShapeOnMeshOrSubMesh( aMeshSO ); + SALOMEDS::SObject_var aMainGeomShapeSO = myStudyAPI.FindObject( aMainGeomShape ); + if ( aMainGeomShapeSO->_is_nil() || !IsFatherOf( mySMESHGUI->GetStudy()->FindObjectID( IO->getEntry() ), aMainGeomShapeSO ) ) { + myGeomShape = GEOM::GEOM_Shape::_nil(); + aString = ""; + } + } + } + } + else if ( myEditCurrentArgument == LineEditC1A1Hyp ) { + // hypotheses + HypoList.clear(); + if ( nbSel >= 1 ) { + SALOME_ListIteratorOfListIO Itinit( mySelection->StoredIObjects() ); + for ( ; Itinit.More(); Itinit.Next() ) { + HypoList.append( Itinit.Value()->getEntry() ); + } + if ( nbSel > 1 ) + aString = tr( "%1 Hypothesis" ).arg( nbSel ) ; + } + else { + aString = ""; } + } + else if ( myEditCurrentArgument == LineEditC1A1Algo ) { + // algorithms + AlgoList.clear(); + if ( nbSel >= 1 ) { + SALOME_ListIteratorOfListIO Itinit( mySelection->StoredIObjects() ); + for ( ; Itinit.More(); Itinit.Next() ) { + AlgoList.append( Itinit.Value()->getEntry() ); + } + if ( nbSel > 1 ) + aString = tr( "%1 Algorithms" ).arg( nbSel ) ; + } + else { + aString = ""; + } + } myEditCurrentArgument->setText(aString) ; + + UpdateControlState(); } @@ -434,36 +401,28 @@ void SMESHGUI_AddSubMeshDlg::SelectionIntoArgument() void SMESHGUI_AddSubMeshDlg::SetEditCurrentArgument() { QPushButton* send = (QPushButton*)sender(); - switch (myConstructorId) - { - case 0: /* default constructor */ - { - if(send == SelectButtonC1A1) { - LineEditC1A1->setFocus() ; - myEditCurrentArgument = LineEditC1A1; - mySelection->ClearFilters() ; - mySelection->AddFilter(myMeshFilter) ; - } else if (send == SelectButtonC1A2) { - LineEditC1A2->setFocus() ; - myEditCurrentArgument = LineEditC1A2; - mySelection->ClearFilters() ; - mySelection->AddFilter(myGeomFilter) ; - } else if( send == SelectButtonC1A1Hyp ) { - LineEditC1A1Hyp->setFocus() ; - myEditCurrentArgument = LineEditC1A1Hyp ; - mySelection->ClearFilters() ; - mySelection->AddFilter(myHypothesisFilter) ; - } else if( send == SelectButtonC1A1Algo ) { - LineEditC1A1Algo->setFocus() ; - myEditCurrentArgument = LineEditC1A1Algo ; - mySelection->ClearFilters() ; - mySelection->AddFilter(myAlgorithmFilter) ; - } - SelectionIntoArgument() ; - break; - } - } - return ; + if(send == SelectButtonC1A1) { + LineEditC1A1->setFocus() ; + myEditCurrentArgument = LineEditC1A1; + mySelection->ClearFilters() ; + mySelection->AddFilter(myMeshFilter) ; + } else if (send == SelectButtonC1A2) { + LineEditC1A2->setFocus() ; + myEditCurrentArgument = LineEditC1A2; + mySelection->ClearFilters() ; + mySelection->AddFilter(myGeomFilter) ; + } else if( send == SelectButtonC1A1Hyp ) { + LineEditC1A1Hyp->setFocus() ; + myEditCurrentArgument = LineEditC1A1Hyp ; + mySelection->ClearFilters() ; + mySelection->AddFilter(myHypothesisFilter) ; + } else if( send == SelectButtonC1A1Algo ) { + LineEditC1A1Algo->setFocus() ; + myEditCurrentArgument = LineEditC1A1Algo ; + mySelection->ClearFilters() ; + mySelection->AddFilter(myAlgorithmFilter) ; + } + SelectionIntoArgument() ; } //================================================================================= @@ -472,9 +431,8 @@ void SMESHGUI_AddSubMeshDlg::SetEditCurrentArgument() //================================================================================= void SMESHGUI_AddSubMeshDlg::DeactivateActiveDialog() { - if ( GroupConstructors->isEnabled() ) { + if ( GroupC1->isEnabled() ) { disconnect( mySelection, 0, this, 0 ); - GroupConstructors->setEnabled(false) ; GroupC1->setEnabled(false) ; GroupButtons->setEnabled(false) ; } @@ -488,11 +446,9 @@ void SMESHGUI_AddSubMeshDlg::DeactivateActiveDialog() void SMESHGUI_AddSubMeshDlg::ActivateThisDialog() { mySMESHGUI->EmitSignalDeactivateDialog() ; - GroupConstructors->setEnabled(true) ; GroupC1->setEnabled(true) ; GroupButtons->setEnabled(true) ; connect ( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) ); - return ; } @@ -502,10 +458,8 @@ void SMESHGUI_AddSubMeshDlg::ActivateThisDialog() //================================================================================= void SMESHGUI_AddSubMeshDlg::enterEvent(QEvent* e) { - if ( GroupConstructors->isEnabled() ) - return ; - ActivateThisDialog() ; - return ; + if ( !GroupC1->isEnabled() ) + ActivateThisDialog() ; } @@ -515,21 +469,31 @@ void SMESHGUI_AddSubMeshDlg::enterEvent(QEvent* e) //================================================================================= void SMESHGUI_AddSubMeshDlg::closeEvent( QCloseEvent* e ) { - this->ClickOnCancel() ; - return ; + disconnect( mySelection, 0, this, 0 ); + mySMESHGUI->ResetState() ; + mySelection->ClearFilters() ; + QDialog::closeEvent( e ); } //================================================================================= -// function : TextChangedInLineEdit() +// function : UpdateControlState() // purpose : //================================================================================= -void SMESHGUI_AddSubMeshDlg::TextChangedInLineEdit(const QString& newText) -{ - QLineEdit* send = (QLineEdit*)sender(); - QString newT = strdup(newText) ; - - if (send == LineEdit_NameMesh) { - myNameSubMesh = newText; +void SMESHGUI_AddSubMeshDlg::UpdateControlState() +{ + bool isEnabled = ( !myMesh->_is_nil() && !myGeomShape->_is_nil() && ( HypoList.count() || AlgoList.count() ) ); + bool isImportedMesh = false; + if ( !myMesh->_is_nil() ) { + SALOMEDS::SObject_var aMeshSO = mySMESHGUI->GetStudyAPI().FindObject( myMesh ); + GEOM::GEOM_Shape_var myGeomShape = mySMESHGUI->GetStudyAPI().GetShapeOnMeshOrSubMesh( aMeshSO ); + isImportedMesh = myGeomShape->_is_nil(); } - return ; + + buttonOk ->setEnabled( isEnabled && !isImportedMesh ); + buttonApply->setEnabled( isEnabled && !isImportedMesh ); } + + + + + diff --git a/src/SMESHGUI/SMESHGUI_AddSubMeshDlg.h b/src/SMESHGUI/SMESHGUI_AddSubMeshDlg.h index 4d26275e0..a9e8d3efa 100644 --- a/src/SMESHGUI/SMESHGUI_AddSubMeshDlg.h +++ b/src/SMESHGUI/SMESHGUI_AddSubMeshDlg.h @@ -34,8 +34,8 @@ #include "SMESH_TypeFilter.hxx" // QT Includes -#include #include +#include // IDL Headers #include @@ -43,18 +43,12 @@ #include CORBA_SERVER_HEADER(GEOM_Shape) #include CORBA_SERVER_HEADER(SMESH_Mesh) -class QVBoxLayout; -class QHBoxLayout; -class QGridLayout; -class QButtonGroup; class QGroupBox; class QLabel; class QLineEdit; class QPushButton; -class QRadioButton; class SMESHGUI; - //================================================================================= // class : SMESHGUI_AddSubMeshDlg // purpose : @@ -67,44 +61,36 @@ public: SMESHGUI_AddSubMeshDlg( QWidget* parent = 0, const char* name = 0, SALOME_Selection* Sel = 0, bool modal = FALSE, WFlags fl = 0 ); ~SMESHGUI_AddSubMeshDlg(); -private: - - void Init( SALOME_Selection* Sel ) ; +protected: void closeEvent( QCloseEvent* e ) ; void enterEvent ( QEvent * ) ; +private: + void Init( SALOME_Selection* Sel ) ; + + void UpdateControlState(); + +private: SMESHGUI* mySMESHGUI ; SALOME_Selection* mySelection ; - GEOM::GEOM_Shape_var myGeomShape ; - int myConstructorId ; - QLineEdit* myEditCurrentArgument; - SMESH::SMESH_Mesh_var myMesh; - SMESH::SMESH_subMesh_var mySubMesh; - - QString myNameSubMesh ; + GEOM::GEOM_Shape_var myGeomShape ; + QLineEdit* myEditCurrentArgument; Handle(SALOME_TypeFilter) myGeomFilter; Handle(SMESH_TypeFilter) myMeshFilter; Handle(SMESH_TypeFilter) myHypothesisFilter; Handle(SMESH_TypeFilter) myAlgorithmFilter; - SALOME_ListIO HypoList; - SALOME_ListIO AlgoList; + QStringList HypoList; + QStringList AlgoList; - bool myOkHypothesis; - bool myOkAlgorithm; - - SMESH::SMESH_Hypothesis_var myHypothesis; - SMESH::SMESH_Hypothesis_var myAlgorithm; - - QButtonGroup* GroupConstructors; - QRadioButton* Constructor1; QGroupBox* GroupButtons; QPushButton* buttonOk; - QPushButton* buttonCancel; QPushButton* buttonApply; + QPushButton* buttonCancel; + QGroupBox* GroupC1; QLabel* TextLabel_NameMesh ; QLineEdit* LineEdit_NameMesh ; @@ -124,22 +110,13 @@ private: QLineEdit* LineEditC1A1Algo; private slots: - - void ConstructorsClicked(int constructorId); void ClickOnOk(); + bool ClickOnApply(); void ClickOnCancel(); - void ClickOnApply(); void SetEditCurrentArgument() ; void SelectionIntoArgument() ; void DeactivateActiveDialog() ; void ActivateThisDialog() ; - void TextChangedInLineEdit(const QString& newText) ; - -protected: - QGridLayout* SMESHGUI_AddSubMeshDlgLayout; - QGridLayout* GroupConstructorsLayout; - QGridLayout* GroupButtonsLayout; - QGridLayout* GroupC1Layout; }; #endif // DIALOGBOX_ADD_SUBMESH_H diff --git a/src/SMESHGUI/SMESHGUI_AddVolumeDlg.cxx b/src/SMESHGUI/SMESHGUI_AddVolumeDlg.cxx index 0ef1e42b0..8953903d5 100644 --- a/src/SMESHGUI/SMESHGUI_AddVolumeDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_AddVolumeDlg.cxx @@ -270,7 +270,7 @@ void SMESHGUI_AddVolumeDlg::ClickOnOk() //================================================================================= void SMESHGUI_AddVolumeDlg::ClickOnCancel() { - QAD_Application::getDesktop()->SetSelectionMode( 4 ); + QAD_Application::getDesktop()->SetSelectionMode( ActorSelection ); disconnect( mySelection, 0, this, 0 ); mySMESHGUI->ResetState() ; mySMESHGUI->EraseSimulationActors(); @@ -297,9 +297,9 @@ void SMESHGUI_AddVolumeDlg::SelectionIntoArgument() if(nbNodes < 1) return ; - if ( mySelection->SelectionMode() != 1 ) { + if ( mySelection->SelectionMode() != NodeSelection ) { QAD_MessageBox::warn1 ( QAD_Application::getDesktop(), tr ("SMESH_WRN_WARNING"), - tr ("SMESH_WRN_SELECTIONMODE_NODES"), tr ("SMESH_BUT_YES") ); + tr ("SMESH_WRN_SELECTIONMODE_NODES"), tr ("SMESH_BUT_OK") ); return; } diff --git a/src/SMESHGUI/SMESHGUI_CreateHypothesesDlg.cxx b/src/SMESHGUI/SMESHGUI_CreateHypothesesDlg.cxx new file mode 100644 index 000000000..fd494fb60 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_CreateHypothesesDlg.cxx @@ -0,0 +1,290 @@ +// SMESH SMESHGUI : GUI for SMESH component +// +// Copyright (C) 2003 CEA +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESHGUI_CreateHypothesesDlg.cxx +// Author : Julia DOROVSKIKH +// Module : SMESH +// $Header$ + +using namespace std; +#include "SMESHGUI_CreateHypothesesDlg.h" +#include "SMESHGUI.h" +#include "SALOME_ListIteratorOfListIO.hxx" + +#include "QAD_Application.h" +#include "QAD_Desktop.h" +#include "utilities.h" + +// QT Includes +#include +#include +#include +#include +#include +#include + +//================================================================================= +// class : SMESHGUI_CreateHypothesesDlg() +// purpose : Constructs a SMESHGUI_CreateHypothesesDlg which is a child of 'parent', with the +// name 'name' and widget flags set to 'f'. +// The dialog will by default be modeless, unless you set 'modal' to +// TRUE to construct a modal dialog. +//================================================================================= +SMESHGUI_CreateHypothesesDlg::SMESHGUI_CreateHypothesesDlg (QWidget* parent, + const char* name, + bool modal, + bool isAlgo) + : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose ), + myIsAlgo( isAlgo ) +{ + MESSAGE("SMESHGUI_CreateHypothesesDlg"); + + if ( !name ) + setName( "SMESHGUI_CreateHypothesesDlg" ); + setCaption( isAlgo ? tr( "SMESH_CREATE_ALGORITHMS" ) : tr( "SMESH_CREATE_HYPOTHESES" ) ); + setSizeGripEnabled( TRUE ); + + QGridLayout* SMESHGUI_CreateHypothesesDlgLayout = new QGridLayout( this ); + SMESHGUI_CreateHypothesesDlgLayout->setSpacing( 6 ); + SMESHGUI_CreateHypothesesDlgLayout->setMargin( 11 ); + + /***************************************************************/ + GroupAlgorithms = new QGroupBox( this, "GroupAlgorithms" ); + GroupAlgorithms->setTitle( isAlgo ? tr("SMESH_AVAILABLE_ALGORITHMS") : tr("SMESH_AVAILABLE_HYPOTHESES") ); + GroupAlgorithms->setColumnLayout(0, Qt::Vertical ); + GroupAlgorithms->layout()->setSpacing( 0 ); + GroupAlgorithms->layout()->setMargin( 0 ); + + QGridLayout* hypLayout = new QGridLayout( GroupAlgorithms->layout() ); + hypLayout->setGeometry( QRect( 12, 18, 139, 250 ) ); + hypLayout->setAlignment( Qt::AlignTop ); + hypLayout->setSpacing( 6 ); + hypLayout->setMargin( 11 ); + + ListAlgoDefinition = new QListView( GroupAlgorithms, "ListAlgoDefinition" ); + ListAlgoDefinition->setMinimumSize( 400, 200 ); + ListAlgoDefinition->addColumn(""); + ListAlgoDefinition->header()->hide(); + ListAlgoDefinition->setSelectionMode(QListView::Single); + ListAlgoDefinition->setResizeMode(QListView::AllColumns); + ListAlgoDefinition->setRootIsDecorated( true ); + + hypLayout->addWidget( ListAlgoDefinition, 0, 0 ); + SMESHGUI_CreateHypothesesDlgLayout->addWidget( GroupAlgorithms, 0, 0 ); + + /***************************************************************/ + GroupButtons = new QGroupBox( this, "GroupButtons" ); + GroupButtons->setColumnLayout( 0, Qt::Vertical ); + GroupButtons->layout()->setSpacing( 0 ); + GroupButtons->layout()->setMargin( 0 ); + QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() ); + GroupButtonsLayout->setAlignment( Qt::AlignTop ); + GroupButtonsLayout->setSpacing( 6 ); + GroupButtonsLayout->setMargin( 11 ); + + buttonApply = new QPushButton( GroupButtons, "buttonApply" ); + buttonApply->setText( tr( "SMESH_BUT_CREATE" ) ); + buttonApply->setAutoDefault( TRUE ); + buttonApply->setDefault( FALSE ); + buttonApply->setEnabled( FALSE ) ; + GroupButtonsLayout->addWidget( buttonApply, 0, 1 ); + + QSpacerItem* spacer_9 = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); + GroupButtonsLayout->addItem( spacer_9, 0, 2 ); + + buttonCancel = new QPushButton( GroupButtons, "buttonCancel" ); + buttonCancel->setText( tr( "SMESH_BUT_CLOSE" ) ); + buttonCancel->setAutoDefault( TRUE ); + buttonCancel->setDefault( TRUE ); + buttonCancel->setEnabled( TRUE ) ; + GroupButtonsLayout->addWidget( buttonCancel, 0, 3 ); + + SMESHGUI_CreateHypothesesDlgLayout->addWidget( GroupButtons, 1, 0 ); + /***************************************************************/ + + Init(); +} + +//================================================================================= +// function : ~SMESHGUI_CreateHypothesesDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +SMESHGUI_CreateHypothesesDlg::~SMESHGUI_CreateHypothesesDlg() +{ + // no need to delete child widgets, Qt does it all for us +} + +//================================================================================= +// function : Init() +// purpose : +//================================================================================= +void SMESHGUI_CreateHypothesesDlg::Init() +{ + mySMESHGUI = SMESHGUI::GetSMESHGUI() ; + mySMESHGUI->SetActiveDialogBox( (QDialog*)this ) ; + + InitAlgoDefinition(); + + /* signals and slots connections */ + connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) ) ; + connect( buttonApply , SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) ) ; + +// connect( mySMESHGUI, SIGNAL ( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ; + connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) ) ; + + connect( ListAlgoDefinition, SIGNAL( selectionChanged() ), this, SLOT( onSelectionChanged() ) ); + connect( ListAlgoDefinition, SIGNAL( doubleClicked(QListViewItem*) ), this, SLOT( onDoubleClicked(QListViewItem*) ) ); + + int x, y ; + mySMESHGUI->DefineDlgPosition( this, x, y ) ; + this->move( x, y ) ; + this->show() ; +} + +//================================================================================= +// function : ClickOnCancel() +// purpose : +//================================================================================= +void SMESHGUI_CreateHypothesesDlg::ClickOnCancel() +{ + close() ; +} + +//================================================================================= +// function : ClickOnApply() +// purpose : +//================================================================================= +void SMESHGUI_CreateHypothesesDlg::ClickOnApply() +{ + QListViewItem* item = ListAlgoDefinition->selectedItem(); + if ( !item ) + return; + QString aHypType = item->text( 1 ); + MESSAGE("Apply " << aHypType); + char* sHypType = (char*)aHypType.latin1(); + + HypothesisData* aHypData = mySMESHGUI->GetHypothesisData(sHypType); + if ( !aHypData ) + return; + QString aClientLibName = aHypData->ClientLibName; + MESSAGE("Client lib name = " << aClientLibName); + + if (aClientLibName == "") + { + // Call hypothesis creation server method (without GUI) + QString aHypName = aHypData->Label; + mySMESHGUI->CreateHypothesis(sHypType, aHypName, myIsAlgo); + } + else + { + // Get hypotheses creator client (GUI) + SMESHGUI_GenericHypothesisCreator* aCreator = + mySMESHGUI->GetHypothesisCreator(sHypType); + + // Create hypothesis/algorithm + aCreator->CreateHypothesis(myIsAlgo, this); + } + +// buttonApply->setEnabled(FALSE); + return; +} + +//================================================================================= +// function : ActivateThisDialog() +// purpose : +//================================================================================= +void SMESHGUI_CreateHypothesesDlg::ActivateThisDialog() +{ + mySMESHGUI->EmitSignalDeactivateDialog() ; + GroupButtons->setEnabled(true) ; + return ; +} + +//================================================================================= +// function : enterEvent() +// purpose : +//================================================================================= +void SMESHGUI_CreateHypothesesDlg::enterEvent(QEvent* e) +{ + ActivateThisDialog() ; + return ; +} + +//================================================================================= +// function : closeEvent() +// purpose : +//================================================================================= +void SMESHGUI_CreateHypothesesDlg::closeEvent( QCloseEvent* e ) +{ + mySMESHGUI->ResetState(); + QDialog::closeEvent( e ); +} + +//================================================================================= +// function : onSelectionChanged() +// purpose : +//================================================================================= +void SMESHGUI_CreateHypothesesDlg::onSelectionChanged() +{ + QListViewItem* item = ListAlgoDefinition->selectedItem(); + buttonApply->setEnabled( item && item->depth() > 0 ) ; +} + +//================================================================================= +// function : onDoubleClicked() +// purpose : +//================================================================================= +void SMESHGUI_CreateHypothesesDlg::onDoubleClicked(QListViewItem* i) +{ + if ( i && i->depth() > 0 ) + this->ClickOnApply(); +} + +//================================================================================= +// function : InitAlgoDefinition() +// purpose : +//================================================================================= +void SMESHGUI_CreateHypothesesDlg::InitAlgoDefinition() +{ + ListAlgoDefinition->clear(); + QStringList HypList = mySMESHGUI->GetAvailableHypotheses(myIsAlgo); + for ( int i = 0; i < HypList.count(); ++i ) { + HypothesisData* aHypData = mySMESHGUI->GetHypothesisData( HypList[i] ); + QListViewItem* parentItem = 0; + QListViewItem* childItem = ListAlgoDefinition->firstChild(); + while ( childItem ) { + if ( childItem->text(0) == aHypData->PluginName ) { + parentItem = childItem; + break; + } + childItem = childItem->nextSibling(); + } + if ( !parentItem ) + parentItem = new QListViewItem( ListAlgoDefinition, aHypData->PluginName ); + parentItem->setOpen( true ); + QListViewItem* aItem = new QListViewItem( parentItem, aHypData->Label, HypList[i] ); + QPixmap aPixMap (QAD_Desktop::getResourceManager()->loadPixmap + ("SMESH", tr(aHypData->IconId))); + if ( !aPixMap.isNull() ) + aItem->setPixmap( 0, aPixMap ); + } +} diff --git a/src/SMESHGUI/SMESHGUI_CreateHypothesesDlg.h b/src/SMESHGUI/SMESHGUI_CreateHypothesesDlg.h new file mode 100644 index 000000000..4fa446d5c --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_CreateHypothesesDlg.h @@ -0,0 +1,97 @@ +// SMESH SMESHGUI : GUI for SMESH component +// +// Copyright (C) 2003 CEA +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESHGUI_CreateHypothesesDlg.h +// Author : Julia DOROVSKIKH +// Module : SMESH +// $Header$ + +#ifndef DIALOGBOX_CREATE_HYPOTHESES_H +#define DIALOGBOX_CREATE_HYPOTHESES_H + +// QT Includes +#include +#include +#include + +// IDL Headers +#include +#include CORBA_SERVER_HEADER(GEOM_Gen) +#include CORBA_SERVER_HEADER(GEOM_Shape) +#include CORBA_SERVER_HEADER(SMESH_Mesh) + +#include +#include + +using namespace std; + +class QButtonGroup; +class QGroupBox; +class QPushButton; +class QListView; +class QListViewItem; +class SMESHGUI; + +//================================================================================= +// class : SMESHGUI_CreateHypothesesDlg +// purpose : +//================================================================================= +class SMESHGUI_CreateHypothesesDlg : public QDialog +{ + Q_OBJECT + +public: + SMESHGUI_CreateHypothesesDlg (QWidget* parent = 0, + const char* name = 0, + bool modal = FALSE, + bool isAlgo = FALSE); + ~SMESHGUI_CreateHypothesesDlg (); + +private: + + void Init() ; + void closeEvent( QCloseEvent* e ) ; + void enterEvent ( QEvent * ) ; + + void InitAlgoDefinition(); + + SMESHGUI* mySMESHGUI; + bool myIsAlgo; + + QGroupBox* GroupButtons; + QPushButton* buttonCancel; + QPushButton* buttonApply; + + QGroupBox* GroupAlgorithms; + QListView* ListAlgoDefinition; + +private slots: + + void ClickOnCancel(); + void ClickOnApply(); + void ActivateThisDialog() ; + + void onSelectionChanged(); + void onDoubleClicked(QListViewItem*); +}; + +#endif // DIALOGBOX_CREATE_HYPOTHESES_H diff --git a/src/SMESHGUI/SMESHGUI_DiagonalInversionDlg.cxx b/src/SMESHGUI/SMESHGUI_DiagonalInversionDlg.cxx index ad086e43e..bc76e32fb 100644 --- a/src/SMESHGUI/SMESHGUI_DiagonalInversionDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_DiagonalInversionDlg.cxx @@ -247,7 +247,7 @@ void SMESHGUI_DiagonalInversionDlg::ClickOnOk() //================================================================================= void SMESHGUI_DiagonalInversionDlg::ClickOnCancel() { - QAD_Application::getDesktop()->SetSelectionMode( 4 ); + QAD_Application::getDesktop()->SetSelectionMode( ActorSelection ); disconnect( mySelection, 0, this, 0 ); mySMESHGUI->ResetState() ; reject() ; @@ -265,7 +265,7 @@ void SMESHGUI_DiagonalInversionDlg::SelectionIntoArgument() myOkElements = false; QString aString = ""; - if ( mySelection->SelectionMode() != 2 ) { + if ( mySelection->SelectionMode() != EdgeSelection ) { return; } diff --git a/src/SMESHGUI/SMESHGUI_EditHypothesesDlg.cxx b/src/SMESHGUI/SMESHGUI_EditHypothesesDlg.cxx index 13f8197c4..7f8c99250 100644 --- a/src/SMESHGUI/SMESHGUI_EditHypothesesDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_EditHypothesesDlg.cxx @@ -33,20 +33,17 @@ using namespace std; #include "QAD_Application.h" #include "QAD_Desktop.h" +#include "QAD_WaitCursor.h" +#include "QAD_Operation.h" + #include "utilities.h" // QT Includes -#include #include #include #include #include -#include #include -#include -#include -#include -#include #include //VRV: porting on Qt 3.0.5 @@ -55,6 +52,38 @@ using namespace std; #endif //VRV: porting on Qt 3.0.5 +class ListBoxIOR : public QListBoxText +{ +public: + enum { RTTI_IOR = 1000 }; + +public: + ListBoxIOR( QListBox* listbox, + const char* ior, + const QString& text = QString::null) + : QListBoxText( listbox, text ), myIOR( ior ) {} + virtual ~ListBoxIOR() {}; + virtual int rtti() const { return RTTI_IOR; } + const char* GetIOR() { return myIOR.c_str(); } + +private: + string myIOR; +}; + +#define ALLOW_CHANGE_SHAPE 0 + +int findItem( QListBox* listBox, const string& ior ) +{ + for ( int i = 0; i < listBox->count(); i++ ) { + if ( listBox->item( i )->rtti() == ListBoxIOR::RTTI_IOR ) { + ListBoxIOR* anItem = ( ListBoxIOR* )( listBox->item( i ) ); + if ( anItem && ior == string( anItem->GetIOR() ) ) + return i; + } + } + return -1; +} + //================================================================================= // class : SMESHGUI_EditHypothesesDlg() // purpose : Constructs a SMESHGUI_EditHypothesesDlg which is a child of 'parent', with the @@ -63,238 +92,131 @@ using namespace std; // TRUE to construct a modal dialog. //================================================================================= SMESHGUI_EditHypothesesDlg::SMESHGUI_EditHypothesesDlg( QWidget* parent, const char* name, SALOME_Selection* Sel, bool modal, WFlags fl ) - : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ) + : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose ), + myImportedMesh( false ) { - QPixmap image1(QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr("ICON_DLG_EDIT_MESH"))); QPixmap image0(QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr("ICON_SELECT"))); if ( !name ) - setName( "SMESHGUI_EditHypothesesDlg" ); - resize( 417, 573 ); + setName( "SMESHGUI_EditHypothesesDlg" ); setCaption( tr( "SMESH_EDIT_HYPOTHESES" ) ); setSizeGripEnabled( TRUE ); - SMESHGUI_EditHypothesesDlgLayout = new QGridLayout( this ); + QGridLayout* SMESHGUI_EditHypothesesDlgLayout = new QGridLayout( this ); SMESHGUI_EditHypothesesDlgLayout->setSpacing( 6 ); SMESHGUI_EditHypothesesDlgLayout->setMargin( 11 ); /***************************************************************/ - GroupConstructors = new QButtonGroup( this, "GroupConstructors" ); - GroupConstructors->setTitle( tr( "SMESH_HYPOTHESES" ) ); - GroupConstructors->setExclusive( TRUE ); - GroupConstructors->setColumnLayout(0, Qt::Vertical ); - GroupConstructors->layout()->setSpacing( 0 ); - GroupConstructors->layout()->setMargin( 0 ); - GroupConstructorsLayout = new QGridLayout( GroupConstructors->layout() ); - GroupConstructorsLayout->setAlignment( Qt::AlignTop ); - GroupConstructorsLayout->setSpacing( 6 ); - GroupConstructorsLayout->setMargin( 11 ); - Constructor1 = new QRadioButton( GroupConstructors, "Constructor1" ); - Constructor1->setText( tr( "" ) ); - Constructor1->setPixmap( image1 ); - Constructor1->setChecked( TRUE ); - Constructor1->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, Constructor1->sizePolicy().hasHeightForWidth() ) ); - Constructor1->setMinimumSize( QSize( 50, 0 ) ); - GroupConstructorsLayout->addWidget( Constructor1, 0, 0 ); - QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); - GroupConstructorsLayout->addItem( spacer, 0, 1 ); - SMESHGUI_EditHypothesesDlgLayout->addWidget( GroupConstructors, 0, 0 ); - - /***************************************************************/ - GroupButtons = new QGroupBox( this, "GroupButtons" ); - GroupButtons->setGeometry( QRect( 10, 10, 281, 96 ) ); - GroupButtons->setTitle( tr( "" ) ); - GroupButtons->setColumnLayout(0, Qt::Vertical ); - GroupButtons->layout()->setSpacing( 0 ); - GroupButtons->layout()->setMargin( 0 ); - GroupButtonsLayout = new QGridLayout( GroupButtons->layout() ); - GroupButtonsLayout->setAlignment( Qt::AlignTop ); - GroupButtonsLayout->setSpacing( 6 ); - GroupButtonsLayout->setMargin( 11 ); - buttonCancel = new QPushButton( GroupButtons, "buttonCancel" ); - buttonCancel->setText( tr( "SMESH_BUT_CLOSE" ) ); - buttonCancel->setAutoDefault( TRUE ); - buttonCancel->setDefault( TRUE ); - buttonCancel->setEnabled( TRUE ) ; - - GroupButtonsLayout->addWidget( buttonCancel, 0, 3 ); - buttonApply = new QPushButton( GroupButtons, "buttonApply" ); - buttonApply->setText( tr( "SMESH_BUT_APPLY" ) ); - buttonApply->setAutoDefault( TRUE ); - buttonApply->setDefault( FALSE ); - buttonApply->setEnabled( FALSE ) ; - - GroupButtonsLayout->addWidget( buttonApply, 0, 1 ); - QSpacerItem* spacer_9 = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); - GroupButtonsLayout->addItem( spacer_9, 0, 2 ); - buttonOk = new QPushButton( GroupButtons, "buttonOk" ); - buttonOk->setText( tr( "SMESH_BUT_OK" ) ); - - buttonOk->setAutoDefault( TRUE ); - buttonOk->setDefault( FALSE ); - buttonOk->setEnabled( FALSE ) ; - - GroupButtonsLayout->addWidget( buttonOk, 0, 0 ); - SMESHGUI_EditHypothesesDlgLayout->addWidget( GroupButtons, 5, 0 ); - - /***************************************************************/ - GroupC1 = new QGroupBox( this, "GroupC1" ); - GroupC1->setTitle( tr( "SMESH_ARGUMENTS" ) ); - GroupC1->setMinimumSize( QSize( 0, 0 ) ); - GroupC1->setFrameShape( QGroupBox::Box ); - GroupC1->setFrameShadow( QGroupBox::Sunken ); + GroupC1 = new QGroupBox( tr( "SMESH_ARGUMENTS" ), this, "GroupC1" ); GroupC1->setColumnLayout(0, Qt::Vertical ); GroupC1->layout()->setSpacing( 0 ); GroupC1->layout()->setMargin( 0 ); - GroupC1Layout = new QGridLayout( GroupC1->layout() ); + QGridLayout* GroupC1Layout = new QGridLayout( GroupC1->layout() ); GroupC1Layout->setAlignment( Qt::AlignTop ); GroupC1Layout->setSpacing( 6 ); GroupC1Layout->setMargin( 11 ); - TextLabelC1A1 = new QLabel( GroupC1, "TextLabelC1A1" ); - TextLabelC1A1->setText( tr( "SMESH_OBJECT_MESHorSUBMESH" ) ); - TextLabelC1A1->setMinimumSize( QSize( 50, 0 ) ); - TextLabelC1A1->setFrameShape( QLabel::NoFrame ); - TextLabelC1A1->setFrameShadow( QLabel::Plain ); + TextLabelC1A1 = new QLabel( tr( "SMESH_OBJECT_MESHorSUBMESH" ), GroupC1, "TextLabelC1A1" ); GroupC1Layout->addWidget( TextLabelC1A1, 0, 0 ); SelectButtonC1A1 = new QPushButton( GroupC1, "SelectButtonC1A1" ); - SelectButtonC1A1->setText( tr( "" ) ); SelectButtonC1A1->setPixmap( image0 ); - SelectButtonC1A1->setToggleButton( FALSE ); GroupC1Layout->addWidget( SelectButtonC1A1, 0, 1 ); LineEditC1A1 = new QLineEdit( GroupC1, "LineEditC1A1" ); GroupC1Layout->addWidget( LineEditC1A1, 0, 2 ); - TextLabelC1A2 = new QLabel( GroupC1, "TextLabelC1A2" ); - TextLabelC1A2->setText( tr( "SMESH_OBJECT_GEOM" ) ); - TextLabelC1A2->setMinimumSize( QSize( 50, 0 ) ); - TextLabelC1A2->setFrameShape( QLabel::NoFrame ); - TextLabelC1A2->setFrameShadow( QLabel::Plain ); + TextLabelC1A2 = new QLabel( tr( "SMESH_OBJECT_GEOM" ), GroupC1, "TextLabelC1A2" ); GroupC1Layout->addWidget( TextLabelC1A2, 1, 0 ); SelectButtonC1A2 = new QPushButton( GroupC1, "SelectButtonC1A2" ); - SelectButtonC1A2->setText( tr( "" ) ); SelectButtonC1A2->setPixmap( image0 ); SelectButtonC1A2->setToggleButton( FALSE ); GroupC1Layout->addWidget( SelectButtonC1A2, 1, 1 ); LineEditC1A2 = new QLineEdit( GroupC1, "LineEditC1A2" ); GroupC1Layout->addWidget( LineEditC1A2, 1, 2 ); - GroupHypotheses = new QGroupBox( this, "GroupHypotheses" ); - GroupHypotheses->setTitle( tr( "SMESH_HYPOTHESES" ) ); + SMESHGUI_EditHypothesesDlgLayout->addWidget( GroupC1, 0, 0 ); + + /***************************************************************/ + GroupHypotheses = new QGroupBox( tr( "SMESH_HYPOTHESES" ), this, "GroupHypotheses" ); GroupHypotheses->setColumnLayout(0, Qt::Vertical ); GroupHypotheses->layout()->setSpacing( 0 ); GroupHypotheses->layout()->setMargin( 0 ); - grid_3 = new QGridLayout( GroupHypotheses->layout() ); - grid_3->setGeometry( QRect( 12, 18, 139, 110 ) ); + QGridLayout* grid_3 = new QGridLayout( GroupHypotheses->layout() ); grid_3->setAlignment( Qt::AlignTop ); grid_3->setSpacing( 6 ); grid_3->setMargin( 11 ); - hbox_2 = new QHBoxLayout; - hbox_2->setSpacing( 6 ); - hbox_2->setMargin( 0 ); - - vbox = new QVBoxLayout; - vbox->setSpacing( 6 ); - vbox->setMargin( 0 ); - - TextHypDefinition = new QLabel( GroupHypotheses, "TextHypDefinition" ); - TextHypDefinition->setText( tr( "SMESH_AVAILABLE" ) ); - vbox->addWidget( TextHypDefinition ); + TextHypDefinition = new QLabel( tr( "SMESH_AVAILABLE" ), GroupHypotheses, "TextHypDefinition" ); + grid_3->addWidget( TextHypDefinition, 0, 0 ); ListHypDefinition = new QListBox( GroupHypotheses, "ListHypDefinition" ); - ListHypDefinition->setMinimumSize( 100, 50); -// ListHypDefinition->setRowMode(4); -// ListHypDefinition->setRowMode( QListBox::FixedNumber ); -// ListHypDefinition->setLineWidth( 4 ); -// ListHypDefinition->setColumnMode( QListBox::Variable ); -// ListHypDefinition->setVariableHeight( FALSE ); -// ListHypDefinition->insertItem( tr( "New Item" ) ); - vbox->addWidget( ListHypDefinition ); - hbox_2->addLayout( vbox ); - - vbox_2 = new QVBoxLayout; - vbox_2->setSpacing( 6 ); - vbox_2->setMargin( 0 ); - - TextHypAssignation = new QLabel( GroupHypotheses, "TextHypAssignation" ); - TextHypAssignation->setText( tr( "SMESH_EDIT_USED" ) ); - vbox_2->addWidget( TextHypAssignation ); + ListHypDefinition->setMinimumSize( 100, 100 ); + grid_3->addWidget( ListHypDefinition, 1, 0 ); + + TextHypAssignation = new QLabel( tr( "SMESH_EDIT_USED" ), GroupHypotheses, "TextHypAssignation" ); + grid_3->addWidget( TextHypAssignation, 0, 1 ); ListHypAssignation = new QListBox( GroupHypotheses, "ListHypAssignation" ); - ListHypAssignation->setMinimumSize( 100, 50); -// ListHypAssignation->setRowMode(4); -// ListHypAssignation->setRowMode( QListBox::FixedNumber ); -// ListHypAssignation->setLineWidth( 4 ); -// ListHypAssignation->setColumnMode( QListBox::Variable ); -// ListHypAssignation->setVariableHeight( FALSE ); -// ListHypAssignation->insertItem( tr( "New Item" ) ); - vbox_2->addWidget( ListHypAssignation ); - hbox_2->addLayout( vbox_2 ); - - grid_3->addLayout( hbox_2, 0, 0 ); - - SMESHGUI_EditHypothesesDlgLayout->addWidget( GroupHypotheses, 2, 0 ); - - GroupAlgorithms = new QGroupBox( this, "GroupAlgorithms" ); - GroupAlgorithms->setTitle( tr( "SMESH_ADD_ALGORITHM" ) ); + ListHypAssignation->setMinimumSize( 100, 100 ); + grid_3->addWidget( ListHypAssignation, 1, 1 ); + + SMESHGUI_EditHypothesesDlgLayout->addWidget( GroupHypotheses, 1, 0 ); + + /***************************************************************/ + GroupAlgorithms = new QGroupBox( tr( "SMESH_ADD_ALGORITHM" ), this, "GroupAlgorithms" ); GroupAlgorithms->setColumnLayout(0, Qt::Vertical ); GroupAlgorithms->layout()->setSpacing( 0 ); GroupAlgorithms->layout()->setMargin( 0 ); - grid_4 = new QGridLayout( GroupAlgorithms->layout() ); - grid_4->setGeometry( QRect( 12, 18, 139, 110 ) ); + QGridLayout* grid_4 = new QGridLayout( GroupAlgorithms->layout() ); grid_4->setAlignment( Qt::AlignTop ); grid_4->setSpacing( 6 ); grid_4->setMargin( 11 ); - hbox_3 = new QHBoxLayout; - hbox_3->setSpacing( 6 ); - hbox_3->setMargin( 0 ); - - vbox_3 = new QVBoxLayout; - vbox_3->setSpacing( 6 ); - vbox_3->setMargin( 0 ); - - TextAlgoDefinition = new QLabel( GroupAlgorithms, "TextAlgoDefinition" ); - TextAlgoDefinition->setText( tr( "SMESH_AVAILABLE" ) ); - vbox_3->addWidget( TextAlgoDefinition ); + TextAlgoDefinition = new QLabel( tr( "SMESH_AVAILABLE" ), GroupAlgorithms, "TextAlgoDefinition" ); + grid_4->addWidget( TextAlgoDefinition, 0, 0 ); ListAlgoDefinition = new QListBox( GroupAlgorithms, "ListAlgoDefinition" ); - ListAlgoDefinition->setMinimumSize( 100, 50); -// ListAlgoDefinition->setRowMode(4); -// ListAlgoDefinition->setRowMode( QListBox::FixedNumber ); -// ListAlgoDefinition->setLineWidth( 4 ); -// ListAlgoDefinition->setColumnMode( QListBox::Variable ); -// ListAlgoDefinition->setVariableHeight( FALSE ); -// ListAlgoDefinition->insertItem( tr( "New Item" ) ); - vbox_3->addWidget( ListAlgoDefinition ); - hbox_3->addLayout( vbox_3 ); - - vbox_4 = new QVBoxLayout; - vbox_4->setSpacing( 6 ); - vbox_4->setMargin( 0 ); - - TextAlgoAssignation = new QLabel( GroupAlgorithms, "TextAlgoAssignation" ); - TextAlgoAssignation->setText( tr( "SMESH_EDIT_USED" ) ); - vbox_4->addWidget( TextAlgoAssignation ); + ListAlgoDefinition->setMinimumSize( 100, 100 ); + grid_4->addWidget( ListAlgoDefinition, 1, 0 ); + + TextAlgoAssignation = new QLabel( tr( "SMESH_EDIT_USED" ), GroupAlgorithms, "TextAlgoAssignation" ); + grid_4->addWidget( TextAlgoAssignation, 0, 1 ); ListAlgoAssignation = new QListBox( GroupAlgorithms, "ListAlgoAssignation" ); - ListAlgoAssignation ->setMinimumSize( 100, 50); -// ListAlgoAssignation->setRowMode(4); -// ListAlgoAssignation->setRowMode( QListBox::FixedNumber ); -// ListAlgoAssignation->setLineWidth( 4 ); -// ListAlgoAssignation->setColumnMode( QListBox::Variable ); -// ListAlgoAssignation->setVariableHeight( FALSE ); -// ListAlgoAssignation->insertItem( tr( "New Item" ) ); - vbox_4->addWidget( ListAlgoAssignation ); - hbox_3->addLayout( vbox_4 ); - - grid_4->addLayout( hbox_3, 0, 0 ); - SMESHGUI_EditHypothesesDlgLayout->addWidget( GroupAlgorithms, 3, 0 ); - - SMESHGUI_EditHypothesesDlgLayout->addWidget( GroupC1, 1, 0 ); + ListAlgoAssignation ->setMinimumSize( 100, 100 ); + grid_4->addWidget( ListAlgoAssignation, 1, 1 ); + + SMESHGUI_EditHypothesesDlgLayout->addWidget( GroupAlgorithms, 2, 0 ); + /***************************************************************/ + GroupButtons = new QGroupBox( this, "GroupButtons" ); + GroupButtons->setColumnLayout(0, Qt::Vertical ); + GroupButtons->layout()->setSpacing( 0 ); + GroupButtons->layout()->setMargin( 0 ); + QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() ); + GroupButtonsLayout->setAlignment( Qt::AlignTop ); + GroupButtonsLayout->setSpacing( 6 ); + GroupButtonsLayout->setMargin( 11 ); - Init(Sel) ; + buttonOk = new QPushButton( tr( "SMESH_BUT_OK" ), GroupButtons, "buttonOk" ); + buttonOk->setAutoDefault( TRUE ); + buttonOk->setDefault( FALSE ); + GroupButtonsLayout->addWidget( buttonOk, 0, 0 ); + + buttonApply = new QPushButton( tr( "SMESH_BUT_APPLY" ), GroupButtons, "buttonApply" ); + buttonApply->setAutoDefault( TRUE ); + buttonApply->setDefault( FALSE ); + GroupButtonsLayout->addWidget( buttonApply, 0, 1 ); + + GroupButtonsLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 2 ); + + buttonCancel = new QPushButton( tr( "SMESH_BUT_CLOSE" ), GroupButtons, "buttonCancel" ); + buttonCancel->setAutoDefault( TRUE ); + buttonCancel->setDefault( TRUE ); + buttonCancel->setEnabled( TRUE ) ; + GroupButtonsLayout->addWidget( buttonCancel, 0, 3 ); + + SMESHGUI_EditHypothesesDlgLayout->addWidget( GroupButtons, 4, 0 ); + /***************************************************************/ + Init(Sel) ; } @@ -314,10 +236,6 @@ SMESHGUI_EditHypothesesDlg::~SMESHGUI_EditHypothesesDlg() //================================================================================= void SMESHGUI_EditHypothesesDlg::Init( SALOME_Selection* Sel ) { - GroupC1->show(); - myConstructorId = 0 ; - Constructor1->setChecked( TRUE ); - myEditCurrentArgument = LineEditC1A1 ; mySelection = Sel; mySMESHGUI = SMESHGUI::GetSMESHGUI() ; mySMESHGUI->SetActiveDialogBox( (QDialog*)this ) ; @@ -325,9 +243,6 @@ void SMESHGUI_EditHypothesesDlg::Init( SALOME_Selection* Sel ) InitHypDefinition(); InitAlgoDefinition(); - InitHypAssignation(); - InitAlgoAssignation(); - myGeomFilter = new SALOME_TypeFilter( "GEOM" ); myMeshOrSubMeshFilter = new SMESH_TypeFilter( MESHorSUBMESH ); @@ -336,52 +251,87 @@ void SMESHGUI_EditHypothesesDlg::Init( SALOME_Selection* Sel ) mySubMesh = SMESH::SMESH_subMesh::_nil(); /* signals and slots connections */ - connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) ) ; - connect( GroupConstructors, SIGNAL(clicked(int) ), SLOT( ConstructorsClicked(int) ) ); + connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) ); + connect( buttonApply, SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) ); + connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) ); - connect( SelectButtonC1A1, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ; - connect( SelectButtonC1A2, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ; + connect( SelectButtonC1A1, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ; + connect( SelectButtonC1A2, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ; - connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) ); - connect( mySMESHGUI, SIGNAL ( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ; - connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) ) ; + connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) ); + connect( mySMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ; + connect( mySMESHGUI, SIGNAL( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) ) ; - connect( ListHypAssignation, SIGNAL( clicked(QListBoxItem*) ), this, SLOT( removeItem(QListBoxItem*) ) ); - connect( ListAlgoAssignation, SIGNAL( clicked(QListBoxItem*) ), this, SLOT( removeItem(QListBoxItem*) ) ); + connect( ListHypAssignation, SIGNAL( doubleClicked(QListBoxItem*) ), this, SLOT( removeItem(QListBoxItem*) ) ); + connect( ListAlgoAssignation, SIGNAL( doubleClicked(QListBoxItem*) ), this, SLOT( removeItem(QListBoxItem*) ) ); - connect( ListHypDefinition, SIGNAL( clicked(QListBoxItem*) ), this, SLOT( addItem(QListBoxItem*) ) ); - connect( ListAlgoDefinition, SIGNAL( clicked(QListBoxItem*) ), this, SLOT( addItem(QListBoxItem*) ) ); + connect( ListHypDefinition, SIGNAL( doubleClicked(QListBoxItem*) ), this, SLOT( addItem(QListBoxItem*) ) ); + connect( ListAlgoDefinition, SIGNAL( doubleClicked(QListBoxItem*) ), this, SLOT( addItem(QListBoxItem*) ) ); int x, y ; mySMESHGUI->DefineDlgPosition( this, x, y ) ; this->move( x, y ) ; this->show() ; + + LineEditC1A1->setFocus() ; + myEditCurrentArgument = LineEditC1A1; + mySelection->ClearFilters() ; + mySelection->AddFilter(myMeshOrSubMeshFilter) ; + SelectionIntoArgument(); - return ; + UpdateControlState(); } //================================================================================= -// function : ConstructorsClicked() -// purpose : Radio button management +// function : ClickOnOk() +// purpose : //================================================================================= -void SMESHGUI_EditHypothesesDlg::ConstructorsClicked(int constructorId) +void SMESHGUI_EditHypothesesDlg::ClickOnOk() { - return ; + if ( ClickOnApply() ) + ClickOnCancel() ; } +//================================================================================= +// function : ClickOnApply() +// purpose : +//================================================================================= +bool SMESHGUI_EditHypothesesDlg::ClickOnApply() +{ + bool aRes = false; + + QAD_WaitCursor wc; + + QAD_Operation* op = new QAD_Operation( mySMESHGUI->GetActiveStudy() ); + + // start transaction + op->start(); + + if ( !myMesh->_is_nil() ) + aRes = StoreMesh(); + else if ( !mySubMesh->_is_nil() ) + aRes = StoreSubMesh(); + + if ( aRes ) + // commit transaction + op->finish(); + else + // abort transaction + op->abort(); + + return aRes; +} + + //================================================================================= // function : ClickOnCancel() // purpose : //================================================================================= void SMESHGUI_EditHypothesesDlg::ClickOnCancel() { - disconnect( mySelection, 0, this, 0 ); - mySMESHGUI->ResetState() ; - mySelection->ClearFilters() ; - reject() ; - return ; + close(); } @@ -391,75 +341,52 @@ void SMESHGUI_EditHypothesesDlg::ClickOnCancel() //================================================================================= void SMESHGUI_EditHypothesesDlg::SelectionIntoArgument() { - myEditCurrentArgument->setText("") ; QString aString = ""; int nbSel = mySMESHGUI->GetNameOfSelectedIObjects(mySelection, aString) ; - - switch (myConstructorId) - { - case 0: - { - if ( myEditCurrentArgument == LineEditC1A1 ) { - if ( nbSel != 1 ) { - myOkHypothesis = false; - myOkAlgorithm = false; - myMesh = SMESH::SMESH_Mesh::_nil(); - mySubMesh = SMESH::SMESH_subMesh::_nil(); - InitHypAssignation(); - InitAlgoAssignation(); - InitGeom(); - return ; - } else { - Standard_Boolean testResult ; - Handle(SALOME_InteractiveObject) IO = mySelection->firstIObject() ; - myMesh = mySMESHGUI->ConvertIOinMesh(IO, testResult) ; - if( !testResult ) { - myMesh = SMESH::SMESH_Mesh::_nil(); - - mySubMesh = mySMESHGUI->ConvertIOinSubMesh(IO, testResult) ; - if( !testResult ) { - mySubMesh = SMESH::SMESH_subMesh::_nil(); - InitHypAssignation(); - InitAlgoAssignation(); - InitGeom(); - return ; - } - } - InitHypAssignation(); - InitAlgoAssignation(); - InitGeom(); - } - } else if ( myEditCurrentArgument == LineEditC1A2 ) { - if ( nbSel != 1 ) { - myOkHypothesis = false; - myOkAlgorithm = false; - myGeomShape = GEOM::GEOM_Shape::_nil(); - InitHypAssignation(); - InitAlgoAssignation(); - InitGeom(); - return ; - } else { - Standard_Boolean testResult ; - Handle(SALOME_InteractiveObject) IO = mySelection->firstIObject() ; - myGeomShape = mySMESHGUI->ConvertIOinGEOMShape(IO, testResult) ; - if( !testResult ) { - myGeomShape = GEOM::GEOM_Shape::_nil(); - InitHypAssignation(); - InitAlgoAssignation(); - InitGeom(); - return ; - } - InitHypAssignation(); - InitAlgoAssignation(); - InitGeom(); - } - } - break; + + if ( myEditCurrentArgument == LineEditC1A1 ) { + if ( nbSel != 1 ) { + myMesh = SMESH::SMESH_Mesh::_nil(); + mySubMesh = SMESH::SMESH_subMesh::_nil(); + aString = ""; + } else { + Standard_Boolean testResult ; + Handle(SALOME_InteractiveObject) IO = mySelection->firstIObject() ; + myMesh = mySMESHGUI->ConvertIOinMesh(IO, testResult) ; + if( !testResult ) { + myMesh = SMESH::SMESH_Mesh::_nil(); + mySubMesh = mySMESHGUI->ConvertIOinSubMesh(IO, testResult) ; + if( !testResult ) { + mySubMesh = SMESH::SMESH_subMesh::_nil(); + aString = ""; + } } } - - myEditCurrentArgument->setText(aString) ; + myEditCurrentArgument->setText( aString ); + + myGeomShape = GEOM::GEOM_Shape::_nil(); // InitGeom() will try to retrieve a shape from myMesh or mySubMesh + InitGeom(); + + myImportedMesh = myGeomShape->_is_nil(); + + InitHypAssignation(); + InitAlgoAssignation(); + } + else if ( myEditCurrentArgument == LineEditC1A2 ) { + if ( nbSel != 1 ) + myGeomShape = GEOM::GEOM_Shape::_nil(); + else { + Standard_Boolean testResult ; + Handle(SALOME_InteractiveObject) IO = mySelection->firstIObject() ; + myGeomShape = mySMESHGUI->ConvertIOinGEOMShape(IO, testResult) ; + if( !testResult ) + myGeomShape = GEOM::GEOM_Shape::_nil(); + } + InitGeom(); + } + + UpdateControlState(); } @@ -470,26 +397,18 @@ void SMESHGUI_EditHypothesesDlg::SelectionIntoArgument() void SMESHGUI_EditHypothesesDlg::SetEditCurrentArgument() { QPushButton* send = (QPushButton*)sender(); - switch (myConstructorId) - { - case 0: /* default constructor */ - { - if(send == SelectButtonC1A1) { - LineEditC1A1->setFocus() ; - myEditCurrentArgument = LineEditC1A1; - mySelection->ClearFilters() ; - mySelection->AddFilter(myMeshOrSubMeshFilter) ; - } else if (send == SelectButtonC1A2) { - LineEditC1A2->setFocus() ; - myEditCurrentArgument = LineEditC1A2; - mySelection->ClearFilters() ; - mySelection->AddFilter(myGeomFilter) ; - } - SelectionIntoArgument() ; - break; - } - } - return ; + if(send == SelectButtonC1A1) { + LineEditC1A1->setFocus() ; + myEditCurrentArgument = LineEditC1A1; + mySelection->ClearFilters() ; + mySelection->AddFilter(myMeshOrSubMeshFilter) ; + } else if (send == SelectButtonC1A2) { + LineEditC1A2->setFocus() ; + myEditCurrentArgument = LineEditC1A2; + mySelection->ClearFilters() ; + mySelection->AddFilter(myGeomFilter) ; + } + SelectionIntoArgument() ; } //================================================================================= @@ -498,9 +417,8 @@ void SMESHGUI_EditHypothesesDlg::SetEditCurrentArgument() //================================================================================= void SMESHGUI_EditHypothesesDlg::DeactivateActiveDialog() { - if ( GroupConstructors->isEnabled() ) { + if ( GroupC1->isEnabled() ) { disconnect( mySelection, 0, this, 0 ); - GroupConstructors->setEnabled(false) ; GroupC1->setEnabled(false) ; GroupButtons->setEnabled(false) ; } @@ -514,11 +432,9 @@ void SMESHGUI_EditHypothesesDlg::DeactivateActiveDialog() void SMESHGUI_EditHypothesesDlg::ActivateThisDialog() { mySMESHGUI->EmitSignalDeactivateDialog() ; - GroupConstructors->setEnabled(true) ; GroupC1->setEnabled(true) ; GroupButtons->setEnabled(true) ; connect ( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) ); - return ; } @@ -528,10 +444,8 @@ void SMESHGUI_EditHypothesesDlg::ActivateThisDialog() //================================================================================= void SMESHGUI_EditHypothesesDlg::enterEvent(QEvent* e) { - if ( GroupConstructors->isEnabled() ) - return ; - ActivateThisDialog() ; - return ; + if ( !GroupC1->isEnabled() ) + ActivateThisDialog(); } @@ -541,72 +455,31 @@ void SMESHGUI_EditHypothesesDlg::enterEvent(QEvent* e) //================================================================================= void SMESHGUI_EditHypothesesDlg::closeEvent( QCloseEvent* e ) { - this->ClickOnCancel() ; - return ; + disconnect( mySelection, 0, this, 0 ); + mySMESHGUI->ResetState() ; + mySelection->ClearFilters() ; + QDialog::closeEvent( e ); } + //================================================================================= -// function : TextChangedInLineEdit() +// function : removeItem() // purpose : //================================================================================= -void SMESHGUI_EditHypothesesDlg::TextChangedInLineEdit(const QString& newText) -{ - QLineEdit* send = (QLineEdit*)sender(); - QString newT = strdup(newText) ; - - return ; -} - -void SMESHGUI_EditHypothesesDlg::removeItem(QListBoxItem* i) +void SMESHGUI_EditHypothesesDlg::removeItem(QListBoxItem* item) { - if (!i) return; + const QObject* aSender = sender(); - SMESHGUI_StudyAPI myStudyAPI = mySMESHGUI->GetStudyAPI(); - int index = ListHypAssignation->index( i ); - if ( index != -1 ) { - if (mapNameIOR.find( string((const char*)(i->text())) ) != mapNameIOR.end()) { - SMESH::SMESH_Hypothesis_var Hyp = - SMESH::SMESH_Hypothesis::_narrow( myStudyAPI.StringToIOR( mapNameIOR[ string((const char*)(i->text())) ].c_str() ) ); - - if ( !myMesh->_is_nil() ) { - SALOMEDS::SObject_var aMesh = myStudyAPI.FindMesh(myMesh); - mySMESHGUI->RemoveHypothesisOrAlgorithmOnMesh(aMesh, Hyp); - // mySMESHGUI->GetStudyAPI().ModifiedMesh( aMesh, false ); - mySMESHGUI->GetActiveStudy()->updateObjBrowser(); - } - if ( !mySubMesh->_is_nil() ) { - SALOMEDS::SObject_var aSubMesh = myStudyAPI.FindSubMesh(mySubMesh); - mySMESHGUI->RemoveHypothesisOrAlgorithmOnMesh(aSubMesh, Hyp); - // mySMESHGUI->GetStudyAPI().ModifiedMesh( aSubMesh, false ); - mySMESHGUI->GetActiveStudy()->updateObjBrowser(); - } - - ListHypAssignation->removeItem( index ); - } - return; - } - index = ListAlgoAssignation->index( i ); - if ( index != -1 ) { - if (mapNameIOR.find( string((const char*)(i->text())) ) != mapNameIOR.end()) { - SMESH::SMESH_Hypothesis_var Hyp = - SMESH::SMESH_Hypothesis::_narrow( myStudyAPI.StringToIOR(mapNameIOR[ string((const char*)(i->text())) ].c_str()) ); - - if ( !myMesh->_is_nil() ) { - SALOMEDS::SObject_var aMesh = myStudyAPI.FindMesh(myMesh); - mySMESHGUI->RemoveHypothesisOrAlgorithmOnMesh(aMesh, Hyp); - // mySMESHGUI->GetStudyAPI().ModifiedMesh( aMesh, false ); - mySMESHGUI->GetActiveStudy()->updateObjBrowser(); - } - if ( !mySubMesh->_is_nil() ) { - SALOMEDS::SObject_var aSubMesh = myStudyAPI.FindSubMesh(mySubMesh); - mySMESHGUI->RemoveHypothesisOrAlgorithmOnMesh(aSubMesh, Hyp); - // mySMESHGUI->GetStudyAPI().ModifiedMesh( aSubMesh, false ); - mySMESHGUI->GetActiveStudy()->updateObjBrowser(); - } + if (!item) return; - ListAlgoAssignation->removeItem( index ); - } + if ( aSender == ListHypAssignation ) { + ListHypAssignation->removeItem( ListHypAssignation->index( item ) ); + } + else if ( aSender == ListAlgoAssignation ) { + ListAlgoAssignation->removeItem( ListAlgoAssignation->index( item ) ); } + + UpdateControlState(); } @@ -614,43 +487,45 @@ void SMESHGUI_EditHypothesesDlg::removeItem(QListBoxItem* i) // function : addItem() // purpose : //================================================================================= -void SMESHGUI_EditHypothesesDlg::addItem(QListBoxItem* i) +void SMESHGUI_EditHypothesesDlg::addItem(QListBoxItem* item) { + const QObject* aSender = sender(); + + if (!item) return; + + ListBoxIOR* i = 0; + if ( item->rtti() == ListBoxIOR::RTTI_IOR ) + i = (ListBoxIOR*)item; if (!i) return; + + bool isFound = false; - SMESHGUI_StudyAPI myStudyAPI = mySMESHGUI->GetStudyAPI(); - if ( ListHypDefinition->findItem( i->text() ) ) { - if ( !ListHypAssignation->findItem( i->text() ) ) { - ListHypAssignation->insertItem( i->text() ); - - if (mapNameIOR.find( string((const char*)(i->text())) ) != mapNameIOR.end()) { - SMESH::SMESH_Hypothesis_var Hyp = - SMESH::SMESH_Hypothesis::_narrow( myStudyAPI.StringToIOR(mapNameIOR[ string((const char*)(i->text())) ].c_str()) ); - - if ( !myMesh->_is_nil() ) - mySMESHGUI->AddHypothesisOnMesh(myMesh, Hyp); - if ( !mySubMesh->_is_nil() ) - mySMESHGUI->AddHypothesisOnSubMesh(mySubMesh, Hyp); + if ( aSender == ListHypDefinition ) { + for ( int j = 0, n = ListHypAssignation->count(); !isFound && j < n; j++ ) { + if ( ListHypAssignation->item( j )->rtti() == ListBoxIOR::RTTI_IOR ) { + ListBoxIOR* anItem = (ListBoxIOR*)ListHypAssignation->item( j ); + isFound = !strcmp( anItem->GetIOR(), i->GetIOR() ); } } - return; + if ( !isFound ) + ListBoxIOR* anItem = new ListBoxIOR( ListHypAssignation, + strdup( i->GetIOR() ), + strdup( i->text().latin1() ) ); } - if ( ListAlgoDefinition->findItem( i->text() ) ) { - if ( !ListAlgoAssignation->findItem( i->text() ) ) { - ListAlgoAssignation->insertItem( i->text() ); - - if (mapNameIOR.find( string((const char*)(i->text())) ) != mapNameIOR.end()) { - SMESH::SMESH_Hypothesis_var Hyp = - SMESH::SMESH_Hypothesis::_narrow( myStudyAPI.StringToIOR(mapNameIOR[ string((const char*)(i->text())) ].c_str()) ); - - if ( !myMesh->_is_nil() ) - mySMESHGUI->AddAlgorithmOnMesh(myMesh, Hyp); - if ( !mySubMesh->_is_nil() ) - mySMESHGUI->AddAlgorithmOnSubMesh(mySubMesh, Hyp); + else if ( aSender == ListAlgoDefinition ) { + for ( int j = 0, n = ListAlgoAssignation->count(); !isFound && j < n; j++ ) { + if ( ListAlgoAssignation->item( j )->rtti() == ListBoxIOR::RTTI_IOR ) { + ListBoxIOR* anItem = (ListBoxIOR*)ListAlgoAssignation->item( j ); + isFound = !strcmp( anItem->GetIOR(), i->GetIOR() ); } } + if ( !isFound ) + ListBoxIOR* anItem = new ListBoxIOR( ListAlgoAssignation, + strdup( i->GetIOR() ), + strdup( i->text().latin1() ) ); } - mySMESHGUI->GetActiveStudy()->updateObjBrowser(); + + UpdateControlState(); } @@ -660,7 +535,12 @@ void SMESHGUI_EditHypothesesDlg::addItem(QListBoxItem* i) //================================================================================= void SMESHGUI_EditHypothesesDlg::InitHypDefinition() { + ListHypDefinition->clear(); + SALOMEDS::SComponent_var father = mySMESHGUI->GetStudy()->FindComponent("MESH"); + if ( father->_is_nil() ) + return; + SALOMEDS::SObject_var HypothesisRoot; SALOMEDS::GenericAttribute_var anAttr; SALOMEDS::AttributeName_var aName; @@ -672,13 +552,13 @@ void SMESHGUI_EditHypothesesDlg::InitHypDefinition() for (; it->More();it->Next()) { SALOMEDS::SObject_var Obj = it->Value(); if (Obj->FindAttribute(anAttr, "AttributeName") ) { - aName = SALOMEDS::AttributeName::_narrow(anAttr); - ListHypDefinition->insertItem(aName->Value()); - - if (Obj->FindAttribute(anAttr, "AttributeIOR")) { - anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - mapNameIOR[ aName->Value() ] = anIOR->Value(); - } + aName = SALOMEDS::AttributeName::_narrow(anAttr); + if (Obj->FindAttribute(anAttr, "AttributeIOR")) { + anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + ListBoxIOR* anItem = new ListBoxIOR( ListHypDefinition, + anIOR->Value(), + aName->Value() ); + } } } } @@ -692,43 +572,41 @@ void SMESHGUI_EditHypothesesDlg::InitHypAssignation() { MESSAGE ( " InitHypAssignation " << myMesh->_is_nil() ) MESSAGE ( " InitHypAssignation " << mySubMesh->_is_nil() ) + + myMapOldHypos.clear(); ListHypAssignation->clear(); - SMESHGUI_StudyAPI myStudyAPI = mySMESHGUI->GetStudyAPI(); - int Tag_RefOnAppliedHypothesis = 2; - SALOMEDS::SObject_var AHR, aRef; + if ( myImportedMesh ) + return; + + SALOMEDS::SObject_var aMorSM, AHR, aRef; SALOMEDS::GenericAttribute_var anAttr; SALOMEDS::AttributeName_var aName; + SALOMEDS::AttributeIOR_var anIOR; + SMESHGUI_StudyAPI myStudyAPI = mySMESHGUI->GetStudyAPI(); - if ( !myMesh->_is_nil() ) { - SALOMEDS::SObject_var aMesh = myStudyAPI.FindMesh( myMesh ); - if ( aMesh->FindSubObject (2, AHR)) { - SALOMEDS::ChildIterator_var it = mySMESHGUI->GetStudy()->NewChildIterator(AHR); - for (; it->More();it->Next()) { - SALOMEDS::SObject_var Obj = it->Value(); - if ( Obj->ReferencedObject(aRef) ) { - if (aRef->FindAttribute(anAttr, "AttributeName") ) { - aName = SALOMEDS::AttributeName::_narrow(anAttr); - ListHypAssignation->insertItem(aName->Value()); + if ( !myMesh->_is_nil() ) + aMorSM = myStudyAPI.FindObject( myMesh ); + else if ( !mySubMesh->_is_nil() ) + aMorSM = myStudyAPI.FindObject( mySubMesh ); + + if ( !aMorSM->_is_nil() && aMorSM->FindSubObject (2, AHR)) { + SALOMEDS::ChildIterator_var it = mySMESHGUI->GetStudy()->NewChildIterator(AHR); + for (; it->More();it->Next()) { + SALOMEDS::SObject_var Obj = it->Value(); + if ( Obj->ReferencedObject(aRef) ) { + if (aRef->FindAttribute(anAttr, "AttributeName") ) { + aName = SALOMEDS::AttributeName::_narrow(anAttr); + if (aRef->FindAttribute(anAttr, "AttributeIOR")) { + anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + ListBoxIOR* anItem = new ListBoxIOR( ListHypAssignation, + anIOR->Value(), + aName->Value() ); + myMapOldHypos[ anIOR->Value() ] = ListHypAssignation->index( anItem ); } } } } } - if ( !mySubMesh->_is_nil() ) { - SALOMEDS::SObject_var aSubMesh = myStudyAPI.FindSubMesh( mySubMesh ); - if ( aSubMesh->FindSubObject (2, AHR)) { - SALOMEDS::ChildIterator_var it = mySMESHGUI->GetStudy()->NewChildIterator(AHR); - for (; it->More();it->Next()) { - SALOMEDS::SObject_var Obj = it->Value(); - if ( Obj->ReferencedObject(aRef) ) { - if (aRef->FindAttribute(anAttr, "AttributeName") ) { - aName = SALOMEDS::AttributeName::_narrow(anAttr); - ListHypAssignation->insertItem(aName->Value()); - } - } - } - } - } } //================================================================================= @@ -737,25 +615,29 @@ void SMESHGUI_EditHypothesesDlg::InitHypAssignation() //================================================================================= void SMESHGUI_EditHypothesesDlg::InitAlgoDefinition() { + ListAlgoDefinition->clear(); + SALOMEDS::SComponent_var father = mySMESHGUI->GetStudy()->FindComponent("MESH"); + if ( father->_is_nil() ) + return; + SALOMEDS::SObject_var AlgorithmsRoot; SALOMEDS::GenericAttribute_var anAttr; SALOMEDS::AttributeName_var aName; SALOMEDS::AttributeIOR_var anIOR; - int Tag_AlgorithmsRoot = 2; if (father->FindSubObject (2, AlgorithmsRoot)) { SALOMEDS::ChildIterator_var it = mySMESHGUI->GetStudy()->NewChildIterator(AlgorithmsRoot); for (; it->More();it->Next()) { SALOMEDS::SObject_var Obj = it->Value(); if (Obj->FindAttribute(anAttr, "AttributeName") ) { - aName = SALOMEDS::AttributeName::_narrow(anAttr); - ListAlgoDefinition->insertItem(aName->Value()); - - if (Obj->FindAttribute(anAttr, "AttributeIOR")) { - anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - mapNameIOR[ aName->Value() ] = anIOR->Value(); - } + aName = SALOMEDS::AttributeName::_narrow(anAttr); + if (Obj->FindAttribute(anAttr, "AttributeIOR")) { + anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + ListBoxIOR* anItem = new ListBoxIOR( ListAlgoDefinition, + anIOR->Value(), + aName->Value() ); + } } } } @@ -770,38 +652,36 @@ void SMESHGUI_EditHypothesesDlg::InitAlgoAssignation() { MESSAGE ( " InitAlgoAssignation " << myMesh->_is_nil() ) MESSAGE ( " InitAlgoAssignation " << mySubMesh->_is_nil() ) + + myMapOldAlgos.clear(); ListAlgoAssignation->clear(); - SMESHGUI_StudyAPI myStudyAPI = mySMESHGUI->GetStudyAPI(); - int Tag_RefOnAppliedAlgorithms = 3; - SALOMEDS::SObject_var AHR, aRef; + if ( myImportedMesh ) + return; + + SALOMEDS::SObject_var aMorSM, AHR, aRef; SALOMEDS::GenericAttribute_var anAttr; SALOMEDS::AttributeName_var aName; - - if ( !myMesh->_is_nil() ) { - SALOMEDS::SObject_var aMesh = myStudyAPI.FindMesh( myMesh ); - if ( aMesh->FindSubObject (3, AHR) ) { - SALOMEDS::ChildIterator_var it = mySMESHGUI->GetStudy()->NewChildIterator(AHR); - for (; it->More();it->Next()) { - SALOMEDS::SObject_var Obj = it->Value(); - if ( Obj->ReferencedObject(aRef) ) { - if (aRef->FindAttribute(anAttr, "AttributeName") ) { - aName = SALOMEDS::AttributeName::_narrow(anAttr); - ListAlgoAssignation->insertItem(aName->Value()); - } - } - } - } - } - if ( !mySubMesh->_is_nil() ) { - SALOMEDS::SObject_var aSubMesh = myStudyAPI.FindSubMesh( mySubMesh ); - if ( aSubMesh->FindSubObject (3, AHR) ) { - SALOMEDS::ChildIterator_var it = mySMESHGUI->GetStudy()->NewChildIterator(AHR); - for (; it->More();it->Next()) { - SALOMEDS::SObject_var Obj = it->Value(); - if ( Obj->ReferencedObject(aRef) ) { - if (aRef->FindAttribute(anAttr, "AttributeName") ) { - aName = SALOMEDS::AttributeName::_narrow(anAttr); - ListAlgoAssignation->insertItem(aName->Value()); + SALOMEDS::AttributeIOR_var anIOR; + SMESHGUI_StudyAPI myStudyAPI = mySMESHGUI->GetStudyAPI(); + + if ( !myMesh->_is_nil() ) + aMorSM = myStudyAPI.FindObject( myMesh ); + else if ( !mySubMesh->_is_nil() ) + aMorSM = myStudyAPI.FindObject( mySubMesh ); + + if ( !aMorSM->_is_nil() && aMorSM->FindSubObject (3, AHR)) { + SALOMEDS::ChildIterator_var it = mySMESHGUI->GetStudy()->NewChildIterator(AHR); + for (; it->More();it->Next()) { + SALOMEDS::SObject_var Obj = it->Value(); + if ( Obj->ReferencedObject(aRef) ) { + if (aRef->FindAttribute(anAttr, "AttributeName") ) { + aName = SALOMEDS::AttributeName::_narrow(anAttr); + if (aRef->FindAttribute(anAttr, "AttributeIOR")) { + anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + ListBoxIOR* anItem = new ListBoxIOR( ListAlgoAssignation, + anIOR->Value(), + aName->Value() ); + myMapOldAlgos[ anIOR->Value() ] = ListAlgoAssignation->index( anItem ); } } } @@ -818,13 +698,13 @@ void SMESHGUI_EditHypothesesDlg::InitGeom() LineEditC1A2->setText("") ; SMESHGUI_StudyAPI myStudyAPI = mySMESHGUI->GetStudyAPI(); - if ( !myMesh->_is_nil() ) { - SALOMEDS::SObject_var aMesh = myStudyAPI.FindMesh( myMesh ); + if ( myGeomShape->_is_nil() && !myMesh->_is_nil() ) { + SALOMEDS::SObject_var aMesh = myStudyAPI.FindObject( myMesh ); if ( !aMesh->_is_nil() ) myGeomShape = myStudyAPI.GetShapeOnMeshOrSubMesh(aMesh); } - if ( !mySubMesh->_is_nil() ) { - SALOMEDS::SObject_var aSubMesh = myStudyAPI.FindSubMesh( mySubMesh ); + if ( myGeomShape->_is_nil() && !mySubMesh->_is_nil() ) { + SALOMEDS::SObject_var aSubMesh = myStudyAPI.FindObject( mySubMesh ); if ( !aSubMesh->_is_nil() ) myGeomShape = myStudyAPI.GetShapeOnMeshOrSubMesh(aSubMesh); } @@ -835,9 +715,203 @@ void SMESHGUI_EditHypothesesDlg::InitGeom() SALOMEDS::SObject_var aSO = mySMESHGUI->GetStudy()->FindObjectIOR( myGeomShape->Name() ); if ( !aSO->_is_nil() ) { if (aSO->FindAttribute(anAttr, "AttributeName") ) { - aName = SALOMEDS::AttributeName::_narrow(anAttr); - LineEditC1A2->setText( QString(aName->Value()) ) ; + aName = SALOMEDS::AttributeName::_narrow(anAttr); + LineEditC1A2->setText( QString(aName->Value()) ) ; + } + } + } +} + +//================================================================================= +// function : UpdateControlState() +// purpose : +//================================================================================= +void SMESHGUI_EditHypothesesDlg::UpdateControlState() +{ + bool isEnabled = ( !myMesh ->_is_nil() && !myGeomShape->_is_nil() && ListHypAssignation->count() && ListAlgoAssignation->count() ) || + ( !mySubMesh->_is_nil() && !myGeomShape->_is_nil() && ( ListHypAssignation->count() || ListAlgoAssignation->count() ) ); + + buttonOk ->setEnabled( isEnabled && !myImportedMesh ); + buttonApply->setEnabled( isEnabled && !myImportedMesh ); + + SelectButtonC1A2 ->setEnabled( ALLOW_CHANGE_SHAPE && !myImportedMesh ); + LineEditC1A2 ->setEnabled( ALLOW_CHANGE_SHAPE && !myImportedMesh ); + ListHypDefinition ->setEnabled( !myImportedMesh ); + ListHypAssignation ->setEnabled( !myImportedMesh ); + ListAlgoDefinition ->setEnabled( !myImportedMesh ); + ListAlgoAssignation->setEnabled( !myImportedMesh ); +} + +//================================================================================= +// function : StoreMesh() +// purpose : +//================================================================================= +bool SMESHGUI_EditHypothesesDlg::StoreMesh() +{ + SMESHGUI_StudyAPI myStudyAPI = mySMESHGUI->GetStudyAPI(); + MapIOR anOldHypos, aNewHypos; + if ( myGeomShape->_is_nil() ) + return false; + // 1. Check whether the geometric shape has changed + SALOMEDS::SObject_var aMeshSO = myStudyAPI.FindObject( myMesh ); + GEOM::GEOM_Shape_var aIniGeomShape = myStudyAPI.GetShapeOnMeshOrSubMesh( aMeshSO ); + bool bShapeChanged = aIniGeomShape->_is_nil() || !aIniGeomShape->_is_equivalent( myGeomShape ); + if ( bShapeChanged ) { + // VSR : TODO : Set new shape - not supported yet by SMESH engine + // 1) remove all old hypotheses and algorithms and also submeshes + // 2) set new shape + } + MapIOR::iterator it; + // 2. remove not used hypotheses from the mesh + for ( it = myMapOldHypos.begin(); it != myMapOldHypos.end(); ++it ) { + string ior = it->first; + int index = findItem( ListHypAssignation, ior ); + if ( index < 0 ) { + CORBA::Object_var anObject = myStudyAPI.StringToIOR( ior.c_str() ); + if ( !CORBA::is_nil( anObject ) ) { + SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( anObject ); + if ( !aHyp->_is_nil() ) + if ( !mySMESHGUI->RemoveHypothesisOrAlgorithmOnMesh( aMeshSO, aHyp ) ) + return false; + } + } + } + // 3. remove not used algorithms from the mesh + for ( it = myMapOldAlgos.begin(); it != myMapOldAlgos.end(); ++it ) { + string ior = it->first; + int index = findItem( ListAlgoAssignation, ior ); + if ( index < 0 ) { + CORBA::Object_var anObject = myStudyAPI.StringToIOR( ior.c_str() ); + if ( !CORBA::is_nil( anObject ) ) { + SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( anObject ); + if ( !aHyp->_is_nil() ) + if ( !mySMESHGUI->RemoveHypothesisOrAlgorithmOnMesh( aMeshSO, aHyp ) ) + return false; + } + } + } + // 4. Add new hypotheses + for ( int i = 0; i < ListHypAssignation->count(); i++ ) { + if ( ListHypAssignation->item( i )->rtti() == ListBoxIOR::RTTI_IOR ) { + ListBoxIOR* anItem = ( ListBoxIOR* )( ListHypAssignation->item( i ) ); + if ( anItem ) { + string ior = anItem->GetIOR(); + if ( myMapOldHypos.find( ior ) == myMapOldHypos.end() ) { + CORBA::Object_var anObject = myStudyAPI.StringToIOR( ior.c_str() ); + if ( !CORBA::is_nil( anObject ) ) { + SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( anObject ); + if ( !aHyp->_is_nil() ) + if ( !mySMESHGUI->AddHypothesisOnMesh( myMesh, aHyp ) ) + return false; + } + } + } + } + } + // 4. Add new algorithms + for ( int i = 0; i < ListAlgoAssignation->count(); i++ ) { + if ( ListAlgoAssignation->item( i )->rtti() == ListBoxIOR::RTTI_IOR ) { + ListBoxIOR* anItem = ( ListBoxIOR* )( ListAlgoAssignation->item( i ) ); + if ( anItem ) { + string ior = anItem->GetIOR(); + if ( myMapOldAlgos.find( ior ) == myMapOldAlgos.end() ) { + CORBA::Object_var anObject = myStudyAPI.StringToIOR( ior.c_str() ); + if ( !CORBA::is_nil( anObject ) ) { + SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( anObject ); + if ( !aHyp->_is_nil() ) + if ( !mySMESHGUI->AddAlgorithmOnMesh( myMesh, aHyp ) ) + return false; + } + } + } + } + } + return true; +} + +//================================================================================= +// function : StoreSubMesh() +// purpose : +//================================================================================= +bool SMESHGUI_EditHypothesesDlg::StoreSubMesh() +{ + SMESHGUI_StudyAPI myStudyAPI = mySMESHGUI->GetStudyAPI(); + MapIOR anOldHypos, aNewHypos; + if ( myGeomShape->_is_nil() ) + return false; + // 1. Check whether the geometric shape has changed + SALOMEDS::SObject_var aSubMeshSO = myStudyAPI.FindObject( mySubMesh ); + GEOM::GEOM_Shape_var aIniGeomShape = myStudyAPI.GetShapeOnMeshOrSubMesh( aSubMeshSO ); + bool bShapeChanged = aIniGeomShape->_is_nil() || !aIniGeomShape->_is_equivalent( myGeomShape ); + if ( bShapeChanged ) { + // VSR : TODO : Set new shape - not supported yet by engine + // 1) remove all old hypotheses and algorithms + // 2) set new shape + } + MapIOR::iterator it; + // 2. remove not used hypotheses from the submesh + for ( it = myMapOldHypos.begin(); it != myMapOldHypos.end(); ++it ) { + string ior = it->first; + int index = findItem( ListHypAssignation, ior ); + if ( index < 0 ) { + CORBA::Object_var anObject = myStudyAPI.StringToIOR( ior.c_str() ); + if ( !CORBA::is_nil( anObject ) ) { + SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( anObject ); + if ( !aHyp->_is_nil() ) + if ( !mySMESHGUI->RemoveHypothesisOrAlgorithmOnMesh( aSubMeshSO, aHyp ) ) + return false; + } + } + } + // 3. remove not used algorithms from the submesh + for ( it = myMapOldAlgos.begin(); it != myMapOldAlgos.end(); ++it ) { + string ior = it->first; + int index = findItem( ListAlgoAssignation, ior ); + if ( index < 0 ) { + CORBA::Object_var anObject = myStudyAPI.StringToIOR( ior.c_str() ); + if ( !CORBA::is_nil( anObject ) ) { + SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( anObject ); + if ( !aHyp->_is_nil() ) + if ( !mySMESHGUI->RemoveHypothesisOrAlgorithmOnMesh( aSubMeshSO, aHyp ) ) + return false; + } + } + } + // 4. Add new hypotheses + for ( int i = 0; i < ListHypAssignation->count(); i++ ) { + if ( ListHypAssignation->item( i )->rtti() == ListBoxIOR::RTTI_IOR ) { + ListBoxIOR* anItem = ( ListBoxIOR* )( ListHypAssignation->item( i ) ); + if ( anItem ) { + string ior = anItem->GetIOR(); + if ( myMapOldHypos.find( ior ) == myMapOldHypos.end() ) { + CORBA::Object_var anObject = myStudyAPI.StringToIOR( ior.c_str() ); + if ( !CORBA::is_nil( anObject ) ) { + SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( anObject ); + if ( !aHyp->_is_nil() ) + if ( !mySMESHGUI->AddHypothesisOnSubMesh( mySubMesh, aHyp ) ) + return false; + } + } + } + } + } + // 4. Add new algorithms + for ( int i = 0; i < ListAlgoAssignation->count(); i++ ) { + if ( ListAlgoAssignation->item( i )->rtti() == ListBoxIOR::RTTI_IOR ) { + ListBoxIOR* anItem = ( ListBoxIOR* )( ListAlgoAssignation->item( i ) ); + if ( anItem ) { + string ior = anItem->GetIOR(); + if ( myMapOldAlgos.find( ior ) == myMapOldAlgos.end() ) { + CORBA::Object_var anObject = myStudyAPI.StringToIOR( ior.c_str() ); + if ( !CORBA::is_nil( anObject ) ) { + SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( anObject ); + if ( !aHyp->_is_nil() ) + if ( !mySMESHGUI->AddAlgorithmOnSubMesh( mySubMesh, aHyp ) ) + return false; + } + } } } } + return true; } diff --git a/src/SMESHGUI/SMESHGUI_EditHypothesesDlg.h b/src/SMESHGUI/SMESHGUI_EditHypothesesDlg.h index 45bf2c4ba..2e707dd49 100644 --- a/src/SMESHGUI/SMESHGUI_EditHypothesesDlg.h +++ b/src/SMESHGUI/SMESHGUI_EditHypothesesDlg.h @@ -34,7 +34,6 @@ #include "SMESH_TypeFilter.hxx" // QT Includes -#include #include // IDL Headers @@ -46,21 +45,15 @@ #include #include -using namespace std; - -class QVBoxLayout; -class QHBoxLayout; -class QGridLayout; -class QButtonGroup; class QGroupBox; class QLabel; class QLineEdit; class QPushButton; -class QRadioButton; class QListBox; class QListBoxItem; class SMESHGUI; +typedef map MapIOR; //================================================================================= // class : SMESHGUI_EditHypothesesDlg @@ -74,11 +67,12 @@ public: SMESHGUI_EditHypothesesDlg( QWidget* parent = 0, const char* name = 0, SALOME_Selection* Sel = 0, bool modal = FALSE, WFlags fl = 0 ); ~SMESHGUI_EditHypothesesDlg(); -private: +protected: + virtual void closeEvent( QCloseEvent* e ); + virtual void enterEvent ( QEvent* ); +private: void Init( SALOME_Selection* Sel ) ; - void closeEvent( QCloseEvent* e ) ; - void enterEvent ( QEvent * ) ; void InitHypDefinition(); void InitAlgoDefinition(); @@ -87,11 +81,16 @@ private: void InitGeom(); + void UpdateControlState(); + + bool StoreMesh(); + bool StoreSubMesh(); + +private: SMESHGUI* mySMESHGUI ; SALOME_Selection* mySelection ; GEOM::GEOM_Shape_var myGeomShape ; - int myConstructorId ; QLineEdit* myEditCurrentArgument; SMESH::SMESH_Mesh_var myMesh; @@ -100,78 +99,46 @@ private: Handle(SALOME_TypeFilter) myGeomFilter; Handle(SMESH_TypeFilter) myMeshOrSubMeshFilter; - map mapNameIOR; - - SALOME_ListIO HypoList; - SALOME_ListIO AlgoList; - - bool myOkHypothesis; - bool myOkAlgorithm; + MapIOR myMapOldHypos, myMapOldAlgos; - SMESH::SMESH_Hypothesis_var myHypothesis; - SMESH::SMESH_Hypothesis_var myAlgorithm; - - SMESH::ListOfHypothesis_var myLHypothesis; - SMESH::ListOfHypothesis_var myLAlgorithm; + bool myImportedMesh; - QButtonGroup* GroupConstructors; - QRadioButton* Constructor1; QGroupBox* GroupButtons; QPushButton* buttonOk; - QPushButton* buttonCancel; QPushButton* buttonApply; - QGroupBox* GroupC1; + QPushButton* buttonCancel; + QGroupBox* GroupC1; QLabel* TextLabelC1A1; QPushButton* SelectButtonC1A1; QLineEdit* LineEditC1A1; - QLabel* TextLabelC1A2; QPushButton* SelectButtonC1A2; QLineEdit* LineEditC1A2; - QGroupBox* GroupHypotheses; - QLabel* TextHypDefinition; - QListBox* ListHypDefinition; - QLabel* TextHypAssignation; - QListBox* ListHypAssignation; + QGroupBox* GroupHypotheses; + QLabel* TextHypDefinition; + QListBox* ListHypDefinition; + QLabel* TextHypAssignation; + QListBox* ListHypAssignation; - QGroupBox* GroupAlgorithms; - QLabel* TextAlgoDefinition; - QListBox* ListAlgoDefinition; - QLabel* TextAlgoAssignation; - QListBox* ListAlgoAssignation; + QGroupBox* GroupAlgorithms; + QLabel* TextAlgoDefinition; + QListBox* ListAlgoDefinition; + QLabel* TextAlgoAssignation; + QListBox* ListAlgoAssignation; private slots: - - void ConstructorsClicked(int constructorId); + void ClickOnOk(); + bool ClickOnApply(); void ClickOnCancel(); void SetEditCurrentArgument() ; void SelectionIntoArgument() ; void DeactivateActiveDialog() ; void ActivateThisDialog() ; - void TextChangedInLineEdit(const QString& newText) ; void removeItem(QListBoxItem*); void addItem(QListBoxItem*); - -protected: - QGridLayout* SMESHGUI_EditHypothesesDlgLayout; - QGridLayout* GroupConstructorsLayout; - QGridLayout* GroupButtonsLayout; - QGridLayout* GroupC1Layout; - - QGridLayout* grid_3; - QGridLayout* grid_4; - - QHBoxLayout* hbox_2; - QHBoxLayout* hbox_3; - - QVBoxLayout* vbox; - QVBoxLayout* vbox_2; - QVBoxLayout* vbox_3; - QVBoxLayout* vbox_4; - }; #endif // DIALOGBOX_EDIT_HYPOTHESES_H diff --git a/src/SMESHGUI/SMESHGUI_Filter.cxx b/src/SMESHGUI/SMESHGUI_Filter.cxx new file mode 100755 index 000000000..22a2e8910 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_Filter.cxx @@ -0,0 +1,114 @@ +// SMESHGUI_Filter : Filters for VTK viewer +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESHGUI_Filter.cxx +// Author : Sergey LITONIN +// Module : SMESH + +#include "SMESHGUI_Filter.h" + +#include + +#include +#include +#include "SMESH_Actor.h" +#include "SMESHGUI.h" + +IMPLEMENT_STANDARD_HANDLE(SMESHGUI_Filter, VTKViewer_Filter) +IMPLEMENT_STANDARD_RTTIEXT(SMESHGUI_Filter, VTKViewer_Filter) + +/* + Class : SMESHGUI_Filter + Description : Selection filter for VTK viewer. This class aggregate object + of SMESH_Filter class and uses it for verification of criterion +*/ + +//======================================================================= +// name : SMESHGUI_Filter::SMESHGUI_Filter +// Purpose : Constructor +//======================================================================= +SMESHGUI_Filter::SMESHGUI_Filter() +{ + myActor = 0; +} + +SMESHGUI_Filter::~SMESHGUI_Filter() +{ +} + +//======================================================================= +// name : SMESHGUI_Filter::IsValid +// Purpose : Verify whether entry id satisfies to criterion of the filter +//======================================================================= +bool SMESHGUI_Filter::IsValid( const int theCellId ) const +{ + if ( myActor == 0 || myPred->_is_nil() ) + return false; + + SMESH_Actor* anActor = ( SMESH_Actor* )myActor; + + int aMeshId = anActor->GetElemObjId( theCellId ); + + return myPred->IsSatisfy( aMeshId ); +} + +//======================================================================= +// name : SMESHGUI_Filter::SetPredicate +// Purpose : Set new pridicate to the filter +//======================================================================= +void SMESHGUI_Filter::SetPredicate( SMESH::Predicate_ptr thePred ) +{ + myPred = thePred; +} + +//======================================================================= +// name : SMESHGUI_Filter::GetActor +// Purpose : Get actor of the filter +//======================================================================= +SALOME_Actor* SMESHGUI_Filter::GetActor() const +{ + return myActor; +} + +//======================================================================= +// name : SMESHGUI_Filter::SetActor +// Purpose : Set new actor +//======================================================================= +void SMESHGUI_Filter::SetActor( SALOME_Actor* theActor ) +{ + if ( myActor == theActor ) + return; + VTKViewer_Filter::SetActor( theActor ); + + if ( myActor != 0 && !myPred->_is_nil() ) + { + Handle(SALOME_InteractiveObject) anIO = myActor->getIO(); + if ( !anIO.IsNull() ) + { + Standard_Boolean aRes = false; + SMESH::SMESH_Mesh_ptr aMeshPtr = SMESHGUI::GetSMESHGUI()->ConvertIOinMesh( anIO, aRes ); + if ( aRes ) + myPred->SetMesh( aMeshPtr ); + } + } +} diff --git a/src/SMESHGUI/SMESHGUI_Filter.h b/src/SMESHGUI/SMESHGUI_Filter.h new file mode 100755 index 000000000..91f3bd700 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_Filter.h @@ -0,0 +1,68 @@ +// SMESHGUI_Filter : Filters for VTK viewer +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESHGUI_Filter.h +// Author : Sergey LITONIN +// Module : SMESH + +#ifndef SMESHGUI_Filter_HeaderFile +#define SMESHGUI_Filter_HeaderFile + +#include "VTKViewer_Filter.h" + +#include +#include CORBA_SERVER_HEADER(SMESH_Filter) + +class SALOME_Actor; + + +DEFINE_STANDARD_HANDLE(SMESHGUI_Filter, VTKViewer_Filter) + +/* + Class : SMESHGUI_Filter + Description : Selection filter for VTK viewer +*/ + +class SMESHGUI_Filter : public VTKViewer_Filter +{ + +public: + SMESHGUI_Filter(); + virtual ~SMESHGUI_Filter(); + + virtual bool IsValid( const int theCellId ) const; + + virtual void SetActor( SALOME_Actor* ); + SALOME_Actor* GetActor() const; + + void SetPredicate( SMESH::Predicate_ptr ); + +private: + + SMESH::Predicate_var myPred; + +public: + DEFINE_STANDARD_RTTI(SMESHGUI_Filter) +}; + +#endif diff --git a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx new file mode 100755 index 000000000..5995bd8ba --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx @@ -0,0 +1,1302 @@ +// SMESH SMESHGUI : GUI for SMESH component +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESHGUI_FilterDlg.cxx +// Author : Sergey LITONIN +// Module : SMESH + +#include "SMESHGUI.h" +#include "SMESHGUI_FilterDlg.h" +#include "SMESHGUI_Filter.h" +#include "SMESH_Actor.h" +#include "VTKViewer_InteractorStyleSALOME.h" +#include "VTKViewer_ViewFrame.h" +#include "QAD_RightFrame.h" +#include "SALOME_ListIteratorOfListIO.hxx" +#include "SALOMEGUI_QtCatchCorbaException.hxx" + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SPACING 5 +#define MARGIN 10 + +static int maxLength( const QStringList& theList, const QFontMetrics& theMetrics ) +{ + int aRes = 0; + QStringList::const_iterator anIter; + for ( anIter = theList.begin(); anIter != theList.end(); ++anIter ) + aRes = Max( aRes, theMetrics.width( *anIter ) ); + return aRes; +} + +/* + Class : SMESHGUI_FilterDlg::Table + Description : Table used by this dialog +*/ + +class SMESHGUI_FilterDlg::Table : public QTable +{ +public: + Table( QWidget* parent = 0 ); + Table( int numRows, int numCols, QWidget* parent = 0 ); + virtual ~Table(); + + void SetEditable( const bool state, const int row, const int col ); + bool IsEditable( const int row, const int col ) const; + + virtual bool eventFilter( QObject *o, QEvent *e ); + virtual void insertRows( int row, int count = 1 ); + virtual QString text( int row, int col ) const; +}; + +SMESHGUI_FilterDlg::Table::Table( QWidget* parent ) +: QTable( parent, "SMESHGUI_FilterDlg::Table" ) +{ +} + +SMESHGUI_FilterDlg::Table::Table( int numRows, int numCols, QWidget* parent ) +: QTable( numRows, numCols, parent, "SMESHGUI_FilterDlg::Table" ) +{ +} + +SMESHGUI_FilterDlg::Table::~Table() +{ +} + +void SMESHGUI_FilterDlg::Table::SetEditable( const bool isEditable, const int row, const int col ) +{ + QTableItem* anItem = item( row, col ); + if( anItem ) + takeItem( anItem ); + + if ( !isEditable ) + { + setItem( row, col, new QTableItem( this, QTableItem::Never, "" ) ); + } + else + { + setItem( row, col, new QTableItem( this, QTableItem::OnTyping, "" ) ); + } +} + +bool SMESHGUI_FilterDlg::Table::IsEditable( const int row, const int col ) const +{ + QTableItem* anItem = item( row, col ); + return anItem == 0 || anItem->editType() != QTableItem::Never; +} + +void SMESHGUI_FilterDlg::Table::insertRows( int row, int count ) +{ + int anEditRow = currEditRow(); + int anEditCol = currEditCol(); + +// printf( "sln: anEditRow = %d, anEditCol = %d\n", anEditRow, anEditCol ); + + if ( anEditRow >= 0 && anEditCol >= 0 ) + endEdit( anEditRow, anEditCol, true, false ); + + QTable::insertRows( row, count ); +} + +QString SMESHGUI_FilterDlg::Table::text( int row, int col ) const +{ + int anEditRow = currEditRow(); + int anEditCol = currEditCol(); + + if ( anEditRow >= 0 && anEditCol >= 0 && anEditRow == row && anEditCol == col ) + ((Table*)this)->endEdit( row, col, true, false ); + + return QTable::text( row, col ); +} + +bool SMESHGUI_FilterDlg::Table::eventFilter( QObject *o, QEvent *e ) +{ + return QTable::eventFilter( o, e ); +} + +/* + Class : SMESHGUI_FilterDlg + Description : Dialog to specify filters for VTK viewer +*/ + + +//======================================================================= +// name : SMESHGUI_FilterDlg::SMESHGUI_FilterDlg +// Purpose : Constructor +//======================================================================= +SMESHGUI_FilterDlg::SMESHGUI_FilterDlg( QWidget* theParent, + const int theType, + const bool theModal, + const char* theName ) +: QDialog( theParent, theName, theModal, + WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ) +{ + myType = theType; + + setCaption( tr( "CAPTION" ) ); + + QVBoxLayout* aDlgLay = new QVBoxLayout( this, MARGIN, SPACING ); + + myMainFrame = createMainFrame ( this ); + QFrame* aBtnFrame = createButtonFrame( this, theModal ); + + aDlgLay->addWidget( myMainFrame ); + aDlgLay->addWidget( aBtnFrame ); + + aDlgLay->setStretchFactor( myMainFrame, 1 ); + + Init( myType ); +} + + +//======================================================================= +// name : SMESHGUI_FilterDlg::createMainFrame +// Purpose : Create frame containing dialog's input fields +//======================================================================= +QFrame* SMESHGUI_FilterDlg::createMainFrame( QWidget* theParent ) +{ + QGroupBox* aMainFrame = new QGroupBox( 1, Qt::Horizontal, theParent ); + aMainFrame->setFrameStyle( QFrame::NoFrame ); + aMainFrame->setInsideMargin( 0 ); + + // filter frame + + QGroupBox* aFilterGrp = new QGroupBox( 1, Qt::Horizontal, tr ( "Filter" ), aMainFrame ); + QFrame* aFilterFrame = new QFrame( aFilterGrp ); + + myTableGrp = new QGroupBox( 1, Qt::Horizontal, aFilterFrame ); + myTableGrp->setFrameStyle( QFrame::NoFrame ); + myTableGrp->setInsideMargin( 0 ); + + myTables[ myType ] = createTable( myTableGrp, myType ); + myAddBtn = new QPushButton( tr( "ADD" ), aFilterFrame ); + myRemoveBtn = new QPushButton( tr( "REMOVE" ), aFilterFrame ); + myClearBtn = new QPushButton( tr( "CLEAR" ), aFilterFrame ); + + QGridLayout* aLay = new QGridLayout( aFilterFrame, 4, 2, 0, SPACING ); + + aLay->addMultiCellWidget( myTableGrp, 0, 3, 0, 0 ); + aLay->addWidget( myAddBtn, 0, 1 ); + aLay->addWidget( myRemoveBtn, 1, 1 ); + aLay->addWidget( myClearBtn, 2, 1 ); + aLay->setColStretch( 0, 1 ); + aLay->setColStretch( 1, 0 ); + + mySetInViewer = new QCheckBox( tr( "SET_IN_VIEWER" ), aFilterGrp ); + mySetInViewer->setChecked( true ); + + QSpacerItem* aVSpacer = new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding ); + aLay->addItem( aVSpacer, 3, 1 ); + + // other controls + mySourceGrp = createSourceGroup( aMainFrame ); + + // signals and slots + connect( myAddBtn, SIGNAL( clicked() ), this, SLOT( onAddBtn() ) ); + connect( myRemoveBtn, SIGNAL( clicked() ), this, SLOT( onRemoveBtn() ) ); + connect( myClearBtn, SIGNAL( clicked() ), this, SLOT( onClearBtn() ) ); + + return aMainFrame; +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::createSourceFrame +// Purpose : Create frame containing source radio button +//======================================================================= +QButtonGroup* SMESHGUI_FilterDlg::createSourceGroup( QWidget* theParent ) +{ + QButtonGroup* aGrp = new QButtonGroup( 1, Qt::Vertical, tr( "SOURCE" ), theParent ); + + QRadioButton* aMeshBtn = new QRadioButton( tr( "MESH" ), aGrp ); + QRadioButton* aSelBtn = new QRadioButton( tr( "SELECTION" ), aGrp ); + QRadioButton* aGrpBtn = new QRadioButton( tr( "CURRENT_GROUP" ), aGrp ); +// QRadioButton* aNoneBtn = new QRadioButton( tr( "NONE" ), aGrp ); + + aGrp->insert( aMeshBtn, Mesh ); + aGrp->insert( aSelBtn, Selection ); + aGrp->insert( aGrpBtn, Dialog ); +// aGrp->insert( aNoneBtn, None ); + + aGrp->setButton( Selection ); + + return aGrp; +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::createTable +// Purpose : Create table +//======================================================================= +SMESHGUI_FilterDlg::Table* SMESHGUI_FilterDlg::createTable( QWidget* theParent, + const int theType ) +{ + // create table + Table* aTable= new Table( 0, 5, theParent ); + + QHeader* aHeaders = aTable->horizontalHeader(); + + QFontMetrics aMetrics( aHeaders->font() ); + + int aLenCr = abs( maxLength( getCriteria( theType ), aMetrics ) - + aMetrics.width( tr( "CRITERION" ) ) ) / aMetrics.width( ' ' ) + 5; + + int aLenCo = abs( maxLength( getCriteria( theType ), aMetrics ) - + aMetrics.width( tr( "COMPARE" ) ) ) / aMetrics.width( ' ' ) + 5; + + QString aCrStr; + aCrStr.fill( ' ', aLenCr ); + QString aCoStr; + aCoStr.fill( ' ', 10 ); + + aHeaders->setLabel( 0, tr( "CRITERION" ) + aCrStr ); + aHeaders->setLabel( 1, tr( "COMPARE" ) + aCoStr ); + aHeaders->setLabel( 2, tr( "THRESHOLD_VALUE" ) ); + aHeaders->setLabel( 3, tr( "UNARY" ) ); + aHeaders->setLabel( 4, tr( "BINARY" ) + " " ); + + // set geometry of the table + + for ( int i = 0; i <= 4; i++ ) + aTable->adjustColumn( i ); + + aTable->updateGeometry(); + QSize aSize = aTable->sizeHint(); + int aWidth = aSize.width(); + aTable->setMinimumSize( QSize( aWidth, aWidth / 2 ) ); + aTable->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding) ); + + if ( theType == SMESH::EDGE ) + connect( aTable, SIGNAL( valueChanged( int, int ) ), + this, SLOT( onCriterionChanged( int, int ) ) ); + + return aTable; +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::createButtonFrame +// Purpose : Create frame containing buttons +//======================================================================= +QFrame* SMESHGUI_FilterDlg::createButtonFrame( QWidget* theParent, const bool theModal ) +{ + QGroupBox* aGrp = new QGroupBox( 1, Qt::Vertical, theParent ); + + myOkBtn = new QPushButton( tr( "SMESH_BUT_OK" ), aGrp ); + myApplyBtn = new QPushButton( tr( "SMESH_BUT_APPLY" ), aGrp ); + QLabel* aLbl = new QLabel( aGrp ); + myCloseBtn = new QPushButton( tr( "SMESH_BUT_CANCEL" ), aGrp ); + + aLbl->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); + + connect( myOkBtn, SIGNAL( clicked() ), SLOT( onOk() ) ); + connect( myCloseBtn, SIGNAL( clicked() ), SLOT( onClose() ) ) ; + connect( myApplyBtn, SIGNAL( clicked() ), SLOT( onApply() ) ); + + if ( theModal ) + myApplyBtn->hide(); + + return aGrp; +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::~SMESHGUI_FilterDlg +// Purpose : Destructor +//======================================================================= +SMESHGUI_FilterDlg::~SMESHGUI_FilterDlg() +{ +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::Init +// Purpose : Init dialog fields, connect signals and slots, show dialog +//======================================================================= +void SMESHGUI_FilterDlg::Init( const int theType ) +{ + mySourceWg = 0; + mySelection = 0; + myType = theType; + myMesh = SMESH::SMESH_Mesh::_nil(); + + // activate corresponding tab + if ( !myTables.contains( myType ) ) + myTables[ myType ] = createTable( myTableGrp, myType ); + + TableMap::iterator anIter; + for ( anIter = myTables.begin(); anIter != myTables.end(); ++anIter ) + if ( anIter.key() == theType ) + anIter.data()->show(); + else + anIter.data()->hide(); + + // set caption + setCaption( myType == SMESH::EDGE ? tr( "EDGES_TLT" ) : tr( "FACES_TLT" ) ); + + qApp->processEvents(); + updateGeometry(); + adjustSize(); + setEnabled( true ); + + mySMESHGUI = SMESHGUI::GetSMESHGUI() ; + mySMESHGUI->SetActiveDialogBox( ( QDialog* )this ) ; + + connect( mySMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), SLOT( onDeactivate() ) ); + connect( mySMESHGUI, SIGNAL( SignalCloseAllDialogs() ), SLOT( onClose() ) ); + + int x, y ; + mySMESHGUI->DefineDlgPosition( this, x, y ); + this->move( x, y ); + + this->show(); + + return; +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::onOk +// Purpose : SLOT called when "Ok" button pressed. +// Assign filters VTK viewer and close dialog +//======================================================================= +void SMESHGUI_FilterDlg::onOk() +{ + if ( onApply() ) + { + disconnect( mySMESHGUI, 0, this, 0 ); + mySMESHGUI->ResetState() ; + accept(); + } + +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::onClose +// Purpose : SLOT called when "Close" button pressed. Close dialog +//======================================================================= +void SMESHGUI_FilterDlg::onClose() +{ + disconnect( mySMESHGUI, 0, this, 0 ); + mySMESHGUI->ResetState() ; + reject() ; + return ; +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::onDeactivate +// Purpose : SLOT called when dialog must be deativated +//======================================================================= +void SMESHGUI_FilterDlg::onDeactivate() +{ + setEnabled( false ); +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::enterEvent +// Purpose : Event filter +//======================================================================= +void SMESHGUI_FilterDlg::enterEvent( QEvent* ) +{ +// mySMESHGUI->EmitSignalDeactivateDialog(); + setEnabled( true ); +} + + +//================================================================================= +// function : closeEvent() +// purpose : +//================================================================================= +void SMESHGUI_FilterDlg::closeEvent( QCloseEvent* e ) +{ + onClose() ; +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::getCriteria +// Purpose : Retrieve list of ids from given widget +//======================================================================= +void SMESHGUI_FilterDlg::getIdsFromWg( const QWidget* theWg, QValueList& theRes ) const +{ + theRes.clear(); + if ( theWg == 0 ) + return; + + if ( theWg->inherits( "QListBox" ) ) + { + QListBox* aListBox = ( QListBox* )theWg; + bool b; + for ( int i = 0, n = aListBox->count(); i < n; i++ ) + { + int anId = aListBox->text( i ).toInt( &b ); + if ( b ) + theRes.append( anId ); + } + } + else if ( theWg->inherits( "QLineEdit" ) ) + { + QLineEdit* aLineEdit = ( QLineEdit* )theWg; + QString aStr = aLineEdit->text(); + QRegExp aRegExp( "(\\d+)" ); + bool b; + int aPos = 0; + while ( aPos >= 0 ) + { + aPos = aRegExp.search( aStr, aPos ); + if ( aPos > -1 ) + { + int anId = aRegExp.cap( 1 ).toInt( &b ); + if ( b ) + theRes.append( anId ); + aPos += aRegExp.matchedLength(); + } + } + } +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::getSelMode +// Purpose : Get criteria for specified type +//======================================================================= +Selection_Mode SMESHGUI_FilterDlg::getSelMode( const int theType ) const +{ + switch ( theType ) + { + case SMESH::NODE : return NodeSelection; + case SMESH::EDGE : return EdgeSelection; + case SMESH::FACE : return FaceSelection; + case SMESH::VOLUME : return VolumeSelection; + default : return ActorSelection; + } + +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::getCriteria +// Purpose : Get criteria for specified type +//======================================================================= +void SMESHGUI_FilterDlg::setIdsToWg( QWidget* theWg, const QValueList& theIds ) +{ + if ( theWg == 0 ) + return; + + if ( theWg->inherits( "QListBox" ) ) + { + QListBox* aListBox = ( QListBox* )theWg; + aListBox->clear(); + + QStringList aStrList; + QValueList::const_iterator anIter; + for ( anIter = theIds.begin(); anIter != theIds.end(); ++anIter ) + aStrList.append( QString( "%1" ).arg( *anIter ) ); + + aListBox->insertStringList( aStrList ); + } + else if ( theWg->inherits( "QLineEdit" ) ) + { + QLineEdit* aLineEdit = ( QLineEdit* )theWg; + QString aStr; + QValueList::const_iterator anIter; + + for ( anIter = theIds.begin(); anIter != theIds.end(); ++ anIter ) + aStr += QString( "%1 " ).arg( *anIter ); + + if ( !aStr.isEmpty() ) + aStr.remove( aStr.length() - 1, 1 ); + + aLineEdit->setText( aStr ); + } +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::getCriteria +// Purpose : Get criteria for specified type +//======================================================================= +const QStringList& SMESHGUI_FilterDlg::getCriteria( const int theType ) const +{ + if ( theType == SMESH::EDGE ) + { + static QStringList aCriteria; + if ( aCriteria.isEmpty() ) + { + aCriteria.append( tr( "FREE_BORDERS" ) ); + aCriteria.append( tr( "MULTI_BORDERS" ) ); + aCriteria.append( tr( "LENGTH" ) ); + } + return aCriteria; + } + else if ( theType == SMESH::FACE ) + { + static QStringList aCriteria; + if ( aCriteria.isEmpty() ) + { + aCriteria.append( tr( "ASPECT_RATIO" ) ); + aCriteria.append( tr( "WARPING" ) ); + aCriteria.append( tr( "MINIMUM_ANGLE" ) ); + aCriteria.append( tr( "TAPER" ) ); + aCriteria.append( tr( "SKEW" ) ); + aCriteria.append( tr( "AREA" ) ); + } + return aCriteria; + } + else + { + static QStringList aCriteria; + return aCriteria; + } +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::getCompare +// Purpose : Get operation of comparison +//======================================================================= +const QStringList& SMESHGUI_FilterDlg::getCompare () const +{ + static QStringList aList; + + if ( aList.isEmpty() ) + { + aList.append( tr( "LESS_THAN" ) ); + aList.append( tr( "MORE_THAN" ) ); + aList.append( tr( "EQUAL_TO" ) ); + } + + return aList; +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::getCriterionItem +// Purpose : Get combo table item for criteria of specified type +//======================================================================= +QTableItem* SMESHGUI_FilterDlg::getCriterionItem( QTable* theParent , const int theType ) +{ + return new QComboTableItem( theParent, getCriteria( theType ) ); +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::getCompareItem +// Purpose : Get combo table item for operation of comparision +//======================================================================= +QTableItem* SMESHGUI_FilterDlg::getCompareItem( QTable* theParent ) +{ + return new QComboTableItem( theParent, getCompare() ); +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::getLogOpItem +// Purpose : +//======================================================================= +QTableItem* SMESHGUI_FilterDlg::getLogOpItem( QTable* theParent ) +{ + static QStringList aList; + if ( aList.isEmpty() ) + { + aList.append( tr( "AND" ) ); + aList.append( tr( "OR" ) ); + } + + return new QComboTableItem( theParent, aList ); +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::getNotItem +// Purpose : Get check table item +//======================================================================= +QTableItem* SMESHGUI_FilterDlg::getNotItem( QTable* theParent ) +{ + return new QCheckTableItem( theParent, tr( "NOT" ) ); +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::getCurrType +// Purpose : Get current entity type +//======================================================================= +int SMESHGUI_FilterDlg::getCurrType() const +{ + return myType; +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::getCriterion +// Purpose : +//======================================================================= +int SMESHGUI_FilterDlg::getCriterion( const int theType, const int theRow ) const +{ + QComboTableItem* anItem = ( QComboTableItem* )myTables[ getCurrType() ]->item( theRow, 0 ); + return anItem->currentItem(); +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::addRow +// Purpose : +//======================================================================= +void SMESHGUI_FilterDlg::addRow( Table* theTable, const int theType ) +{ + theTable->insertRows( theTable->numRows() ); + int aCurrRow = theTable->numRows() - 1; + + // Criteria + theTable->setItem( aCurrRow, 0, getCriterionItem( theTable, theType ) ); + + // Compare + theTable->setItem( aCurrRow, 1, getCompareItem( theTable ) ); + + //Logical operation NOT + theTable->setItem( aCurrRow, 3, getNotItem( theTable ) ); + + // Logical binary operation for previous value + if ( aCurrRow > 0 ) + theTable->setItem( aCurrRow - 1, 4, getLogOpItem( theTable ) ); + theTable->SetEditable( false, aCurrRow, 4 ); + + onCriterionChanged( aCurrRow, 0 ); +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::onAddBtn +// Purpose : SLOT. Called then "Add" button pressed. +// Adds new string to table +//======================================================================= +void SMESHGUI_FilterDlg::onAddBtn() +{ + // QTable + int aType = getCurrType(); + Table* aTable = myTables[ aType ]; + + addRow( aTable, aType ); + + updateBtnState(); + +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::onCriterionChanged() +// Purpose : SLOT. Called then contents of table changed +// Provides reaction on change of criterion +//======================================================================= +void SMESHGUI_FilterDlg::onCriterionChanged( int row, int col ) +{ + int aType = getCurrType(); + if ( aType != SMESH::EDGE || col != 0 ) + return; + + Table* aTable = myTables[ aType ]; + QComboTableItem* aCompareItem = (QComboTableItem*)aTable->item( row, 1 ); + + if ( getCriterion( aType, row ) != FreeBorders ) + { + if ( aCompareItem->count() == 0 ) + aCompareItem->setStringList( getCompare() ); + + QString aText = aTable->text( row, 2 ); + aTable->SetEditable( true, row, 2 ); + aTable->setText( row, 2, aText ); + } + else + { + if ( aCompareItem->count() > 0 ) + aCompareItem->setStringList( QStringList() ); + aTable->SetEditable( false, row, 2 ); + } +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::onRemoveBtn +// Purpose : SLOT. Called then "Remove" button pressed. +// Removes current string from table +//======================================================================= +void SMESHGUI_FilterDlg::onRemoveBtn() +{ + Table* aTable = myTables[ getCurrType() ]; + + if ( aTable->numRows() == 0 ) + return; + + QMemArray aRows; + for ( int i = 0, n = aTable->numRows(); i < n; i++ ) + { + if ( aTable->isRowSelected( i ) ) + { + aRows.resize( aRows.size() + 1 ); + aRows[ aRows.size() - 1 ] = i; + } + } + + aTable->removeRows( aRows ); + + // remove control of binary logical operation from last row + if ( aTable->numRows() > 0 ) + aTable->SetEditable( false, aTable->numRows() - 1, 4 ); + + updateBtnState(); +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::onClearBtn +// Purpose : SLOT. Called then "Clear" button pressed. +// Removes all strings from table +//======================================================================= +void SMESHGUI_FilterDlg::onClearBtn() +{ + QTable* aTable = myTables[ getCurrType() ]; + + if ( aTable->numRows() == 0 ) + return; + + while ( aTable->numRows() > 0 ) + aTable->removeRow( 0 ); + + updateBtnState(); +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::updateBtnState +// Purpose : Update button state +//======================================================================= +void SMESHGUI_FilterDlg::updateBtnState() +{ + myRemoveBtn->setEnabled( myTables[ getCurrType() ]->numRows() > 0 ); + myClearBtn->setEnabled( myTables[ getCurrType() ]->numRows() > 0 ); +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::isValid +// Purpose : Verify validity of input data +//======================================================================= +bool SMESHGUI_FilterDlg::isValid() const +{ + Table* aTable = myTables[ getCurrType() ]; + for ( int i = 0, n = aTable->numRows(); i < n; i++ ) + { + bool isEditable = aTable->IsEditable( i ,2 ); + bool aRes = false; + int aThreshold = ( int )aTable->text( i, 2 ).toDouble( &aRes ); + if ( isEditable && !aRes ) + { + QMessageBox::information( mySMESHGUI->GetDesktop(), + tr( "SMESH_INSUFFICIENT_DATA" ), tr( "ERROR" ), + QMessageBox::Ok ); + return false; + } + else if ( getCurrType() == SMESH::EDGE && + getCriterion( SMESH::EDGE, i ) == MultiBorders && + aThreshold == 1 ) + { + QMessageBox::information( mySMESHGUI->GetDesktop(), + tr( "SMESH_INSUFFICIENT_DATA" ), tr( "MULTIEDGES_ERROR" ), + QMessageBox::Ok ); + return false; + } + } + + return true; +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::GetResultIds +// Purpose : Get filtered ids +//======================================================================= +/*void SMESHGUI_FilterDlg::GetResultIds( SMESH::SMESH_Mesh_ptr theMesh, + QValueList& theIds ) const +{ + if ( !myPredicate->_is_nil() ) + theIds = myInputIds; + else + myPredicate->SetMesh( theMesh ); + + theIds.clear(); + QValueList::const_iterator anIter; + for ( anIter = myInputIds.begin(); anIter != myInputIds.end(); ++anIter ) + if ( myPredicate->IsSatisfy( *anIter ) ) + theIds.append( *anIter ); +} +*/ + +//======================================================================= +// name : SMESHGUI_FilterDlg::SetSourceWg +// Purpose : Set widget of parent dialog containing idsto be filtered if +// user select corresponding source radio button +//======================================================================= +void SMESHGUI_FilterDlg::SetSourceWg( QWidget* theWg ) +{ + mySourceWg = theWg; +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::SetGroupIds +// Purpose : Set mesh +//======================================================================= +void SMESHGUI_FilterDlg::SetMesh( SMESH::SMESH_Mesh_ptr theMesh ) +{ + myMesh = theMesh; +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::SetSelection +// Purpose : Get filtered ids +//======================================================================= +void SMESHGUI_FilterDlg::SetSelection( SALOME_Selection* theSel ) +{ + mySelection = theSel; +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::onApply +// Purpose : SLOT called when "Apply" button pressed. +// Assign filters to VTK viewer +//======================================================================= +bool SMESHGUI_FilterDlg::onApply() +{ + if ( !isValid() ) + return false; + + try + { + int aCurrType = getCurrType(); + + SMESH::Predicate_ptr aPredicate = createPredicate( aCurrType ); + + if ( mySetInViewer->isChecked() ) + insertFilterInViewer( aPredicate ); + + if ( !aPredicate->_is_nil() ) + { + QValueList aResultIds; + filterSource( aCurrType, aPredicate, aResultIds ); + selectInViewer( aCurrType, aResultIds ); + } + } + catch( const SALOME::SALOME_Exception& S_ex ) + { + QtCatchCorbaException( S_ex ); + } + catch( ... ) + { + } + + return true; +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::createPredicate +// Purpose : Create predicate for given type +//======================================================================= +SMESH::Predicate_ptr SMESHGUI_FilterDlg::createPredicate( const int theType ) +{ + SMESH::FilterManager_ptr aFilterMgr = mySMESHGUI->GetFilterMgr(); + if ( aFilterMgr->_is_nil() ) + return SMESH::Predicate::_nil(); + + QTable* aTable = myTables[ theType ]; + if ( aTable == 0 ) + return SMESH::Predicate::_nil(); + + // CREATE two lists ( PREDICATES and LOG OP ) + + // Criterion + QValueList aPredicates; + QValueList aLogOps; + for ( int i = 0, n = aTable->numRows(); i < n; i++ ) + { + int aCriterion = getCriterion( theType, i ); + + SMESH::Predicate_ptr aPredicate = SMESH::Predicate::_nil(); + SMESH::NumericalFunctor_ptr aFunctor = SMESH::NumericalFunctor::_nil(); + + if ( theType == SMESH::EDGE ) + { + switch ( aCriterion ) + { + case FreeBorders: + aPredicate = aFilterMgr->CreateFreeBorders(); + break; + case MultiBorders: + aFunctor = aFilterMgr->CreateMultiConnection(); + break; + case Length: + aFunctor = aFilterMgr->CreateLength(); + break; + default: + continue; + } + } + else + { + switch ( aCriterion ) + { + case AspectRatio: + aFunctor = aFilterMgr->CreateAspectRatio(); + break; + case Warping: + aFunctor = aFilterMgr->CreateWarping(); + break; + case MinimumAngle: + aFunctor = aFilterMgr->CreateMinimumAngle(); + break; + case Taper: + aFunctor = aFilterMgr->CreateTaper(); + break; + case Skew: + aFunctor = aFilterMgr->CreateSkew(); + break; + case Area: + aFunctor = aFilterMgr->CreateArea(); + break; + default: + continue; + } + } + + // Comparator + if ( !aFunctor->_is_nil() && aPredicate->_is_nil() ) + { + QComboTableItem* aCombo = (QComboTableItem*)aTable->item( i, 1 ); + int aCompareOp = aCombo->currentItem(); + double aThreshold = aTable->text( i, 2 ).toDouble(); + + SMESH::Comparator_ptr aComparator = SMESH::Comparator::_nil(); + + if ( aCompareOp == LessThan ) + aComparator = aFilterMgr->CreateLessThan(); + else if ( aCompareOp == MoreThan ) + aComparator = aFilterMgr->CreateMoreThan(); + else if ( aCompareOp == EqualTo ) + aComparator = aFilterMgr->CreateEqualTo(); + else + continue; + + aComparator->SetNumFunctor( aFunctor ); + aComparator->SetMargin( aThreshold ); + + aPredicate = aComparator; + } + + // Logical not + QCheckTableItem* anItem = (QCheckTableItem*)aTable->item( i, 3 ); + if ( anItem->isChecked() ) + { + SMESH::LogicalNOT_ptr aNotPred = aFilterMgr->CreateLogicalNOT(); + aNotPred->SetPredicate( aPredicate ); + aPredicate = aNotPred; + } + + // logical op + int aLogOp = ( i == n - 1 ) ? LO_Undefined + : ( (QComboTableItem*)aTable->item( i, 4 ) )->currentItem(); + aPredicates.append( aPredicate ); + aLogOps.append( aLogOp ); + + } // for + + // CREATE ONE PREDICATE FROM PREVIOUSLY CREATED MAP + + // combine all "AND" operations + + QValueList aResList; + + QValueList::iterator aPredIter; + QValueList::iterator aLogOpIter; + + SMESH::Predicate_ptr aPrevPredicate = SMESH::Predicate::_nil(); + int aPrevLogOp = LO_Undefined; + + for ( aPredIter = aPredicates.begin(), aLogOpIter = aLogOps.begin(); + aPredIter != aPredicates.end() && aLogOpIter != aLogOps.end(); + ++aPredIter, ++aLogOpIter ) + { + int aCurrLogOp = *aLogOpIter; + + SMESH::Predicate_ptr aCurrPred = SMESH::Predicate::_nil(); + + if ( aPrevLogOp == LO_And ) + { + + SMESH::LogicalBinary_ptr aBinaryPred = aFilterMgr->CreateLogicalAND(); + aBinaryPred->SetPredicate1( aPrevPredicate ); + aBinaryPred->SetPredicate2( *aPredIter ); + aCurrPred = aBinaryPred; + } + else + aCurrPred = *aPredIter; + + if ( aCurrLogOp != LO_And ) + aResList.append( aCurrPred ); + + aPrevPredicate = aCurrPred; + aPrevLogOp = aCurrLogOp; + } + + // combine all "OR" operations + + SMESH::Predicate_ptr aResPredicate = SMESH::Predicate::_nil(); + + if ( aResList.count() == 1 ) + aResPredicate = aResList.first(); + else if ( aResList.count() > 1 ) + { + QValueList::iterator anIter = aResList.begin(); + aResPredicate = *anIter; + anIter++; + for ( ; anIter != aResList.end(); ++anIter ) + { + SMESH::LogicalBinary_ptr aBinaryPred = aFilterMgr->CreateLogicalOR(); + aBinaryPred->SetPredicate1( aResPredicate ); + aBinaryPred->SetPredicate2( *anIter ); + aResPredicate = aBinaryPred; + } + } + + return aResPredicate; +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::insertFilterInViewer +// Purpose : Insert filter in viewer +//======================================================================= +void SMESHGUI_FilterDlg::insertFilterInViewer( SMESH::Predicate_ptr thePred ) +{ + VTKViewer_InteractorStyleSALOME* aStyle = ((VTKViewer_ViewFrame*)mySMESHGUI->GetActiveStudy()-> + getActiveStudyFrame()->getRightFrame()->getViewFrame())-> + getRWInteractor()->GetInteractorStyleSALOME(); + + if ( thePred->_is_nil() ) + { + if ( myType == SMESH::EDGE ) + aStyle->RemoveEdgeFilter(); + else if ( myType == SMESH::FACE ) + aStyle->RemoveFaceFilter(); + } + else + { + Handle(SMESHGUI_Filter) aFilter = new SMESHGUI_Filter(); + aFilter->SetPredicate( thePred ); + if ( myType == SMESH::EDGE ) + aStyle->SetEdgeFilter( aFilter ); + else if ( myType == SMESH::FACE ) + aStyle->SetFaceFilter( aFilter ); + } +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::filterSource +// Purpose : Filter source ids +//======================================================================= +void SMESHGUI_FilterDlg::filterSource( const int theType, + SMESH::Predicate_ptr thePred, + QValueList& theResIds ) +{ + theResIds.clear(); + + int aSourceId = mySourceGrp->id( mySourceGrp->selected() ); + + if ( aSourceId == Mesh ) + { + if ( myMesh->_is_nil() ) + return; + SMESH::FilterManager_ptr aFilterMgr = mySMESHGUI->GetFilterMgr(); + SMESH::Filter_var aFilter = aFilterMgr->CreateFilter(); + aFilter->SetPredicate( thePred ); + SMESH::long_array_var anIds = aFilter->GetElementsId( myMesh ); + for ( int i = 0, n = anIds->length(); i < n; i++ ) + theResIds.append( anIds[ i ] ); + } + else if ( aSourceId == Selection ) + { + filterSelectionSource( theType, thePred, theResIds ); + } + else if ( aSourceId == Dialog ) + { + // retrieve ids from dialog + QValueList aDialogIds; + getIdsFromWg( mySourceWg, aDialogIds ); + + if ( myMesh->_is_nil() ) + { + theResIds = aDialogIds; + return; + } + + // filter ids + thePred->SetMesh( myMesh ); + QValueList::const_iterator anIter; + for ( anIter = aDialogIds.begin(); anIter != aDialogIds.end(); ++ anIter ) + if ( thePred->IsSatisfy( *anIter ) ) + theResIds.append( *anIter ); + + // set ids to the dialog + setIdsToWg( mySourceWg, theResIds ); + } +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::filterSelectionSource +// Purpose : Filter source selection +//======================================================================= +void SMESHGUI_FilterDlg::filterSelectionSource( const int theType, + SMESH::Predicate_ptr thePred, + QValueList& theResIds ) +{ + theResIds.clear(); + if ( myMesh->_is_nil() || mySelection == 0 ) + return; + + // Create map of entities to be filtered + TColStd_MapOfInteger aToBeFiltered; + Standard_Boolean aRes = false; + SALOME_ListIteratorOfListIO anIter( mySelection->StoredIObjects() ); + + for ( ; anIter.More(); anIter.Next() ) + { + // process sub mesh + SMESH::SMESH_subMesh_ptr aSubMesh = mySMESHGUI->ConvertIOinSubMesh( anIter.Value(), aRes ); + if ( aRes && !aSubMesh->_is_nil() ) + { + if ( aSubMesh->GetFather()->GetId() == myMesh->GetId() ) + { + SMESH::long_array_var anIds = + theType == SMESH::NODE ? aSubMesh->GetNodesId() : aSubMesh->GetElementsId(); + for ( int i = 0, n = anIds->length(); i < n; i++ ) + aToBeFiltered.Add( anIds[ i ] ); + } + } + + // process group + SMESH::SMESH_Group_ptr aGroup = mySMESHGUI->ConvertIOinSMESHGroup( anIter.Value(), aRes ); + if ( aRes && !aGroup->_is_nil() ) + { + if ( aGroup->GetType() == theType && aGroup->GetMesh()->GetId() == myMesh->GetId() ) + { + SMESH::long_array_var anIds = aGroup->GetListOfID(); + for ( int i = 0, n = anIds->length(); i < n; i++ ) + aToBeFiltered.Add( anIds[ i ] ); + } + } + + // process mesh + SMESH::SMESH_Mesh_ptr aMeshPtr = mySMESHGUI->ConvertIOinMesh( anIter.Value(), aRes ); + if ( aRes && !aMeshPtr->_is_nil() && aMeshPtr->GetId() == myMesh->GetId() ) + { + TColStd_MapOfInteger aVtkMap; + mySelection->GetIndex( anIter.Value(), aVtkMap ); + + if ( aVtkMap.Extent() > 0 ) + { + SMESH_Actor *anActor = mySMESHGUI->FindActorByEntry( + anIter.Value()->getEntry(), aRes, true ); + if ( aRes && anActor != 0 ) + { + TColStd_MapIteratorOfMapOfInteger aVtkMapIter( aVtkMap ); + for ( ; aVtkMapIter.More(); aVtkMapIter.Next() ) + aToBeFiltered.Add( theType == SMESH::NODE + ? anActor->GetNodeObjId( aVtkMapIter.Key() ) + : anActor->GetElemObjId( aVtkMapIter.Key() ) ); + } + } + } + } + + // Filter entities + thePred->SetMesh( myMesh ); + TColStd_MapIteratorOfMapOfInteger aResIter( aToBeFiltered ); + for ( ; aResIter.More(); aResIter.Next() ) + if ( thePred->IsSatisfy( aResIter.Key() ) ) + theResIds.append( aResIter.Key() ); +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::selectInViewer +// Purpose : Select given entities in viewer +//======================================================================= +void SMESHGUI_FilterDlg::selectInViewer( const int theType, const QValueList& theIds ) +{ + if ( mySelection == 0 || myMesh->_is_nil() ) + return; + + // Set new selection mode if necessary + Selection_Mode aSelMode = getSelMode( theType ); + if ( aSelMode != mySelection->SelectionMode() ) + { + mySelection->ClearIObjects(); + mySelection->ClearFilters(); + if ( aSelMode == NodeSelection ) + mySMESHGUI->ViewNodes(); + QAD_Application::getDesktop()->SetSelectionMode( aSelMode ); + } + + Standard_Boolean aRes = false; + SMESH_Actor* anActor = mySMESHGUI->FindActor( myMesh, aRes, true ); + if ( !aRes || anActor == 0 || !anActor->hasIO() ) + return; + + Handle(SALOME_InteractiveObject) anIO = anActor->getIO(); + mySelection->ClearIObjects(); + mySelection->AddIObject( anIO, false ); + + TColStd_MapOfInteger aMap; + QValueList::const_iterator anIter; + for ( anIter = theIds.begin(); anIter != theIds.end(); ++anIter ) + { + std::vector aVtkList = anActor->GetElemVtkId( *anIter ); + std::vector::iterator it; + for ( it = aVtkList.begin(); it != aVtkList.end(); ++it ) + aMap.Add( *it ); + } + + mySelection->AddOrRemoveIndex( anIO, aMap, false, true ); + +} + + + + + + + + + + + + + + + + + + + + diff --git a/src/SMESHGUI/SMESHGUI_FilterDlg.h b/src/SMESHGUI/SMESHGUI_FilterDlg.h new file mode 100755 index 000000000..6ba1d4a79 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_FilterDlg.h @@ -0,0 +1,195 @@ +// SMESH SMESHGUI : GUI for SMESH component +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESHGUI_FilterDlg.h +// Author : Sergey LITONIN +// Module : SMESH + + +#ifndef SMESHGUI_FilterDlg_H +#define SMESHGUI_FilterDlg_H + +#include +#include +#include +#include + +#include +#include CORBA_SERVER_HEADER(SMESH_Filter) +#include CORBA_SERVER_HEADER(SMESH_Mesh) + +class QCloseEvent; +class QWidgetStack; +class QStringList; +class QTableItem; +class QFrame; +class QEvent; +class QPushButton; +class QTable; +class SALOME_Selection; +class SMESHGUI; +class QComboBox; +class QButtonGroup; +class QCheckBox; +class QGroupBox; + + +/* + Class : SMESHGUI_FilterDlg + Description : Dialog to specify filters for VTK viewer +*/ + +class SMESHGUI_FilterDlg : public QDialog +{ + Q_OBJECT + + class Table; + + // Edge criteria + enum { FreeBorders = 0, MultiBorders, Length }; + + // Face criteria + enum { AspectRatio = 0, Warping, MinimumAngle, Taper, Skew, Area }; + + // Comparision + enum { LessThan = 0, MoreThan, EqualTo }; + + // Logical operations + enum { LO_And = 0, LO_Or, LO_Undefined }; + + // Source elements to be selected + enum { Mesh, Selection, Dialog, None }; + + typedef QMap TableMap; + +public: + SMESHGUI_FilterDlg( QWidget* parent, + const int type, + const bool theModal = true, + const char* name = 0 ); + virtual ~SMESHGUI_FilterDlg(); + + void Init( const int type ); + + void SetSelection( SALOME_Selection* ); + void SetMesh( SMESH::SMESH_Mesh_ptr ); + void SetSourceWg( QWidget* ); + +private slots: + + void onAddBtn(); + void onRemoveBtn(); + void onClearBtn(); + void onCriterionChanged( int, int ); + + void onOk(); + bool onApply(); + void onClose(); + void onDeactivate(); + +private: + + void closeEvent( QCloseEvent* e ); + void enterEvent ( QEvent * ); + + void updateBtnState(); + + // dialog creation + QFrame* createButtonFrame( QWidget*, const bool ); + QFrame* createMainFrame( QWidget* ); + Table* createTable( QWidget*, const int ); + QButtonGroup* createSourceGroup( QWidget* ); + void addRow( Table*, const int ); + QTableItem* getCriterionItem( QTable*, const int ); + QTableItem* getCompareItem( QTable* ); + QTableItem* getNotItem( QTable* ); + QTableItem* getLogOpItem( QTable* ); + const QStringList& getCriteria( const int theType ) const; + const QStringList& getCompare () const; + + // query + int getCurrType() const; + int getCriterion( const int theType, const int theRow ) const; + + // execution + bool isValid() const; + SMESH::Predicate_ptr createPredicate( const int theType ); + void insertFilterInViewer( SMESH::Predicate_ptr thePred ); + void selectInViewer( const int theType, + const QValueList& theIds ); + void filterSource( const int theType, + SMESH::Predicate_ptr thePred, + QValueList& theResIds ); + void filterSelectionSource( const int theType, + SMESH::Predicate_ptr thePred, + QValueList& theResIds ); + void getIdsFromWg( const QWidget*, QValueList& ) const; + void setIdsToWg( QWidget*, const QValueList& ); + Selection_Mode getSelMode( const int ) const; + +private: + + // widgets + QFrame* myMainFrame; + QGroupBox* myTableGrp; + + TableMap myTables; + QPushButton* myAddBtn; + QPushButton* myRemoveBtn; + QPushButton* myClearBtn; + QButtonGroup* mySourceGrp; + QCheckBox* mySetInViewer; + + QPushButton* myOkBtn; + QPushButton* myApplyBtn; + QPushButton* myCloseBtn; + + // initial fields + int myType; + SMESHGUI* mySMESHGUI; + SALOME_Selection* mySelection; + SMESH::SMESH_Mesh_ptr myMesh; + QWidget* mySourceWg; +}; + +#endif + + + + + + + + + + + + + + + + + + + + diff --git a/src/SMESHGUI/SMESHGUI_GroupDlg.cxx b/src/SMESHGUI/SMESHGUI_GroupDlg.cxx new file mode 100644 index 000000000..d6928d673 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_GroupDlg.cxx @@ -0,0 +1,977 @@ +// SMESH SMESHGUI : GUI for SMESH component +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESHGUI_GroupDlg.cxx +// Author : Natalia KOPNOVA +// Module : SMESH +// $Header$ + +using namespace std; +#include "SMESHGUI_GroupDlg.h" +#include "SMESHGUI_FilterDlg.h" + +#include "SMESHGUI.h" +#include "SALOMEGUI_QtCatchCorbaException.hxx" +#include "SALOME_ListIteratorOfListIO.hxx" +#include "VTKViewer_InteractorStyleSALOME.h" +#include "VTKViewer_ViewFrame.h" +#include "QAD_Application.h" +#include "QAD_Desktop.h" +#include "QAD_MessageBox.h" +#include "QAD_RightFrame.h" +#include "utilities.h" + +#include "SMESH_Actor.h" + +// QT Includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// STL includes +#include +#include + +//================================================================================= +// class : SMESHGUI_GroupDlg() +// purpose : +//================================================================================= +SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( QWidget* parent, const char* name, SALOME_Selection* theSel, + SMESH::SMESH_Mesh_ptr theMesh, bool modal, WFlags fl ) + : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose ) +{ + if ( !name ) setName( "SMESHGUI_GroupDlg" ); + initDialog(theSel, true); + init(theMesh); + + /* Move widget on the botton right corner of main widget */ + int x, y ; + mySMESHGUI->DefineDlgPosition(this, x, y); + this->move(x, y); +} + +SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( QWidget* parent, const char* name, SALOME_Selection* theSel, + SMESH::SMESH_Group_ptr theGroup, bool modal, WFlags fl ) + : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose ) +{ + if ( !name ) setName( "SMESHGUI_GroupDlg" ); + initDialog(theSel, false); + init(theGroup); + + /* Move widget on the botton right corner of main widget */ + int x, y ; + mySMESHGUI->DefineDlgPosition(this, x, y); + this->move(x, y); +} + +void SMESHGUI_GroupDlg::initDialog(SALOME_Selection* theSel, bool create) +{ + myFilterDlg = 0; + + QPixmap image0(QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr("ICON_SELECT"))); + + if (create) + setCaption( tr( "SMESH_CREATE_GROUP_TITLE" ) ); + else + setCaption( tr( "SMESH_EDIT_GROUP_TITLE" ) ); + setSizeGripEnabled( TRUE ); + + QVBoxLayout* aMainLayout = new QVBoxLayout(this, 11, 6); + + /***************************************************************/ + myTypeGroup = new QButtonGroup(1, Qt::Vertical, this, "Group types"); + myTypeGroup->setTitle(tr("SMESH_ELEMENTS_TYPE")); + myTypeGroup->setExclusive(true); + + QStringList types; + types.append(tr("MESH_NODE")); + types.append(tr("SMESH_EDGE")); + types.append(tr("SMESH_FACE")); + types.append(tr("SMESH_VOLUME")); + QRadioButton* rb; + for (int i = 0; i < types.count(); i++) { + rb = new QRadioButton(types[i], myTypeGroup); + } + myTypeGroup->setEnabled(create); + myTypeId = -1; + + /***************************************************************/ + QHBox* aNameBox = new QHBox(this, "name box"); + QLabel* aName = new QLabel(aNameBox, "name label"); + aName->setText(tr("SMESH_NAME")); + aName->setMinimumSize(50,0); + myName = new QLineEdit(aNameBox, "name"); + + /***************************************************************/ + QGroupBox* aContentBox = new QGroupBox(1, Qt::Horizontal, this, "content box"); + aContentBox->setTitle(tr("SMESH_CONTENT")); + QFrame* aContent = new QFrame(aContentBox, "content"); + QGridLayout* aLayout = new QGridLayout(aContent, 7, 4); + aLayout->setSpacing(6); + aLayout->setAutoAdd(false); + + QLabel* aLabel = new QLabel(aContent, "elements label"); + aLabel->setText(tr("SMESH_ID_ELEMENTS")); + myElements = new QListBox(aContent, "elements list"); + myElements->setSelectionMode(QListBox::Extended); + // myElements->setMinimumHeight(150); + + myFilter = new QPushButton(aContent, "filter"); + myFilter->setText(tr("SMESH_BUT_FILTER")); + QPushButton* aAddBtn = new QPushButton(aContent, "add"); + aAddBtn->setText(tr("SMESH_BUT_ADD")); + QPushButton* aRemoveBtn = new QPushButton(aContent, "remove"); + aRemoveBtn->setText(tr("SMESH_BUT_REMOVE")); + QPushButton* aSortBtn = new QPushButton(aContent, "sort"); + aSortBtn->setText(tr("SMESH_BUT_SORT")); + + aLayout->addWidget(aLabel, 0, 0); + aLayout->addMultiCellWidget(myElements, 1, 6, 0, 0); + aLayout->addWidget(myFilter, 1, 2); + aLayout->addWidget(aAddBtn, 3, 2); + aLayout->addWidget(aRemoveBtn, 4, 2); + aLayout->addWidget(aSortBtn, 6, 2); + + aLayout->setColStretch(0, 1); + aLayout->addColSpacing(1, 20); + aLayout->addColSpacing(3, 20); + aLayout->setRowStretch(2, 1); + aLayout->setRowStretch(5, 1); + + aContentBox->setMinimumHeight(aContent->sizeHint().height() + + aContentBox->sizeHint().height()); + + /***************************************************************/ + QGroupBox* aSelectBox = new QGroupBox(3, Qt::Horizontal, this, "select box"); + aSelectBox->setTitle(tr("SMESH_SELECT_FROM")); + + mySelectSubMesh = new QCheckBox(aSelectBox, "submesh checkbox"); + mySelectSubMesh->setText(tr("SMESH_SUBMESH")); + mySelectSubMesh->setMinimumSize(50, 0); + mySubMeshBtn = new QPushButton(aSelectBox, "submesh button"); + mySubMeshBtn->setText(""); + mySubMeshBtn->setPixmap(image0); + mySubMeshLine = new QLineEdit(aSelectBox, "submesh line"); + mySubMeshLine->setReadOnly(true); + onSelectSubMesh(false); + + mySelectGroup = new QCheckBox(aSelectBox, "group checkbox"); + mySelectGroup->setText(tr("SMESH_GROUP")); + mySelectGroup->setMinimumSize(50, 0); + myGroupBtn = new QPushButton(aSelectBox, "group button"); + myGroupBtn->setText(""); + myGroupBtn->setPixmap(image0); + myGroupLine = new QLineEdit(aSelectBox, "group line"); + myGroupLine->setReadOnly(true); + onSelectGroup(false); + + aSelectBox->setMinimumHeight(mySubMeshBtn->sizeHint().height() + + myGroupBtn->sizeHint().height() + + aSelectBox->sizeHint().height()); + + /***************************************************************/ + QFrame* aButtons = new QFrame(this, "button box"); + aButtons->setFrameStyle(QFrame::Box | QFrame::Sunken); + QHBoxLayout* aBtnLayout = new QHBoxLayout(aButtons, 11, 6); + aBtnLayout->setAutoAdd(false); + + QPushButton* aOKBtn = new QPushButton(aButtons, "ok"); + aOKBtn->setText(tr("SMESH_BUT_OK")); + aOKBtn->setAutoDefault(true); + aOKBtn->setDefault(true); + QPushButton* aApplyBtn = new QPushButton(aButtons, "apply"); + aApplyBtn->setText(tr("SMESH_BUT_APPLY")); + aApplyBtn->setAutoDefault(true); + QPushButton* aCloseBtn = new QPushButton(aButtons, "close"); + aCloseBtn->setText(tr("SMESH_BUT_CLOSE")); + aCloseBtn->setAutoDefault(true); + + aBtnLayout->addWidget(aOKBtn); + aBtnLayout->addWidget(aApplyBtn); + aBtnLayout->addStretch(); + aBtnLayout->addWidget(aCloseBtn); + + /***************************************************************/ + aMainLayout->addWidget(myTypeGroup); + aMainLayout->addWidget(aNameBox); + aMainLayout->addWidget(aContentBox); + aMainLayout->addWidget(aSelectBox); + aMainLayout->addWidget(aButtons); + + /* signals and slots connections */ + connect(myTypeGroup, SIGNAL(clicked(int)), this, SLOT(onTypeChanged(int))); + + connect(myName, SIGNAL(textChanged(const QString&)), this, SLOT(onNameChanged(const QString&))); + connect(myElements, SIGNAL(selectionChanged()), this, SLOT(onListSelectionChanged())); + + connect(myFilter, SIGNAL(clicked()), this, SLOT(setFilters())); + connect(aAddBtn, SIGNAL(clicked()), this, SLOT(onAdd())); + connect(aRemoveBtn, SIGNAL(clicked()), this, SLOT(onRemove())); + connect(aSortBtn, SIGNAL(clicked()), this, SLOT(onSort())); + + connect(mySelectSubMesh, SIGNAL(toggled(bool)), this, SLOT(onSelectSubMesh(bool))); + connect(mySelectGroup, SIGNAL(toggled(bool)), this, SLOT(onSelectGroup(bool))); + connect(mySubMeshBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); + connect(myGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); + + connect(aOKBtn, SIGNAL(clicked()), this, SLOT(onOK())); + connect(aApplyBtn, SIGNAL(clicked()), this, SLOT(onApply())); + connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(onClose())); + + /* Init selection */ + mySelection = theSel; + mySMESHGUI = SMESHGUI::GetSMESHGUI(); + mySMESHGUI->SetActiveDialogBox(this); + mySMESHGUI->SetState(800); + + mySelectionMode = -1; + mySubMeshFilter = new SMESH_TypeFilter(SUBMESH); + myGroupFilter = new SMESH_TypeFilter(GROUP); + + connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(onClose())); + connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(onClose())); + connect(mySelection, SIGNAL(currentSelectionChanged()), this, SLOT(onObjectSelectionChanged())); + + updateButtons(); +} + +//================================================================================= +// function : ~SMESHGUI_GroupDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +SMESHGUI_GroupDlg::~SMESHGUI_GroupDlg() +{ + // no need to delete child widgets, Qt does it all for us +} + + +//================================================================================= +// function : Init() +// purpose : +//================================================================================= +void SMESHGUI_GroupDlg::init(SMESH::SMESH_Mesh_ptr theMesh) +{ + /* init data from current selection */ + myMesh = SMESH::SMESH_Mesh::_duplicate(theMesh); + myGroup = SMESH::SMESH_Group::_nil(); + + Standard_Boolean aResult; + myActor = mySMESHGUI->FindActor(myMesh, aResult, true); + mySMESHGUI->SetPickable(myActor); + + myTypeGroup->setButton(0); + onTypeChanged(0); +} + +//================================================================================= +// function : Init() +// purpose : +//================================================================================= +void SMESHGUI_GroupDlg::init(SMESH::SMESH_Group_ptr theGroup) +{ + + myMesh = theGroup->GetMesh(); + myGroup = SMESH::SMESH_Group::_duplicate(theGroup); + + Standard_Boolean aResult; + myActor = mySMESHGUI->FindActor(myMesh, aResult, true); + if ( !myActor ) + myActor = mySMESHGUI->FindActor(myGroup, aResult, true); + mySMESHGUI->SetPickable(myActor); + + int aType = 0; + switch(theGroup->GetType()) { + case SMESH::NODE: aType= 0; break; + case SMESH::EDGE: aType = 1; break; + case SMESH::FACE: aType = 2; break; + case SMESH::VOLUME: aType = 3; break; + } + myTypeGroup->setButton(aType); + onTypeChanged(aType); + + myName->setText(myGroup->GetName()); + myName->home(false); + + if (!theGroup->IsEmpty()) { + SMESH::long_array_var anElements = myGroup->GetListOfID(); + int k = anElements->length(); + for (int i = 0; i < k; i++) { + myIdList.append(anElements[i]); + myElements->insertItem(QString::number(anElements[i])); + } + myElements->selectAll(true); + } +} + + +//================================================================================= +// function : updateButtons() +// purpose : +//================================================================================= +void SMESHGUI_GroupDlg::updateButtons() +{ + bool enable = !myName->text().stripWhiteSpace().isEmpty() && myElements->count() > 0; + QPushButton* aBtn; + aBtn = (QPushButton*) child("ok", "QPushButton"); + if (aBtn) aBtn->setEnabled(enable); + aBtn = (QPushButton*) child("apply", "QPushButton"); + if (aBtn) aBtn->setEnabled(enable); +} + +//================================================================================= +// function : onNameChanged() +// purpose : +//================================================================================= +void SMESHGUI_GroupDlg::onNameChanged(const QString& text) +{ + updateButtons(); +} + +//================================================================================= +// function : onTypeChanged() +// purpose : Radio button management +//================================================================================= +void SMESHGUI_GroupDlg::onTypeChanged(int id) +{ + if (myTypeId != id) { + myElements->clear(); + if (myCurrentLineEdit == 0) + setSelectionMode(id); + myFilter->setEnabled(id == 1 || id == 2); + } + myTypeId = id; +} + +//================================================================================= +// function : setSelectionMode() +// purpose : Radio button management +//================================================================================= +void SMESHGUI_GroupDlg::setSelectionMode(int theMode) +{ + if (mySelectionMode != theMode) { + mySelection->ClearIObjects(); + mySelection->ClearFilters(); + if (mySelectionMode == 0) + mySMESHGUI->EraseSimulationActors(); + if (theMode < 4) { + if (theMode == 0) { + mySMESHGUI->ViewNodes(); + QAD_Application::getDesktop()->SetSelectionMode(NodeSelection, true); + } + else if (theMode == 1) { + QAD_Application::getDesktop()->SetSelectionMode(EdgeSelection, true); + } + else if (theMode == 2) { + QAD_Application::getDesktop()->SetSelectionMode(FaceSelection, true); + } + else { + QAD_Application::getDesktop()->SetSelectionMode(VolumeSelection, true); + } + } + else { + QAD_Application::getDesktop()->SetSelectionMode(ActorSelection, true); + if (theMode == 4) + mySelection->AddFilter(mySubMeshFilter); + else if (theMode == 5) + mySelection->AddFilter(myGroupFilter); + } + mySelectionMode = theMode; + } +} + +//================================================================================= +// function : onApply() +// purpose : +//================================================================================= +bool SMESHGUI_GroupDlg::onApply() +{ + if (!myName->text().stripWhiteSpace().isEmpty() && myElements->count() > 0) { + mySelection->ClearIObjects(); + if (myGroup->_is_nil()) { + SMESH::ElementType aType = SMESH::ALL; + switch(myTypeId) { + case 0: aType = SMESH::NODE; break; + case 1: aType = SMESH::EDGE; break; + case 2: aType = SMESH::FACE; break; + case 3: aType = SMESH::VOLUME; break; + } + SMESH::long_array_var anIdList = new SMESH::long_array; + int i, k = myElements->count(); + anIdList->length(k); + QListBoxItem* anItem; + for (i = 0, anItem = myElements->firstItem(); anItem != 0; i++, anItem = anItem->next()) { + anIdList[i] = anItem->text().toInt(); + } + + myGroup = mySMESHGUI->AddGroup(myMesh, aType, myName->text()); + myGroup->Add(anIdList); + + /* init for next operation */ + myName->setText(""); + myElements->clear(); + myGroup = SMESH::SMESH_Group::_nil(); + } + else { + myGroup->SetName(myName->text()); + + QValueList aAddList; + QValueList::iterator anIt; + QListBoxItem* anItem; + for (anItem = myElements->firstItem(); anItem != 0; anItem = anItem->next()) { + int anId = anItem->text().toInt(); + if ((anIt = myIdList.find(anId)) == myIdList.end()) + aAddList.append(anId); + else + myIdList.remove(anIt); + } + if (!aAddList.empty()) { + SMESH::long_array_var anIdList = new SMESH::long_array; + anIdList->length(aAddList.count()); + int i; + for (i = 0, anIt = aAddList.begin(); anIt != aAddList.end(); anIt++, i++) + anIdList[i] = *anIt; + myGroup->Add(anIdList); + } + if (!myIdList.empty()) { + SMESH::long_array_var anIdList = new SMESH::long_array; + anIdList->length(myIdList.count()); + int i; + for (i = 0, anIt = myIdList.begin(); anIt != myIdList.end(); anIt++, i++) + anIdList[i] = *anIt; + myGroup->Remove(anIdList); + } + /* init for next operation */ + myIdList.clear(); + for (anItem = myElements->firstItem(); anItem != 0; anItem = anItem->next()) + myIdList.append(anItem->text().toInt()); + } + + mySMESHGUI->GetActiveStudy()->updateObjBrowser(true); + mySelection->ClearIObjects(); + return true; + } + return false; +} + +//================================================================================= +// function : onOK() +// purpose : +//================================================================================= +void SMESHGUI_GroupDlg::onOK() +{ + if ( onApply() ) + onClose(); +} + +//================================================================================= +// function : onClose() +// purpose : +//================================================================================= +void SMESHGUI_GroupDlg::onClose() +{ + close(); +} + + +static bool busy = false; +//================================================================================= +// function : onListSelectionChanged() +// purpose : Called when selection in element list is changed +//================================================================================= +void SMESHGUI_GroupDlg::onListSelectionChanged() +{ + // MESSAGE("SMESHGUI_GroupDlg::onListSelectionChanged(); myActor = " << myActor); + if (busy || !myActor) return; + busy = true; + + if (myCurrentLineEdit == 0) { + mySelection->ClearIObjects(); + TColStd_MapOfInteger aIndexes; + QListBoxItem* anItem; + for (anItem = myElements->firstItem(); anItem != 0; anItem = anItem->next()) { + if (anItem->isSelected()) { + std::vector aVtkList; + if (myTypeId == 0) + aVtkList = myActor->GetNodeVtkId(anItem->text().toInt()); + else + aVtkList = myActor->GetElemVtkId(anItem->text().toInt()); + + if (aVtkList.size() > 0) { + std::vector::iterator it; + for (it = aVtkList.begin(); it != aVtkList.end(); ++it) { + aIndexes.Add(*it); + } + } + } + } + mySelection->AddOrRemoveIndex(myActor->getIO(), aIndexes, false, false); + mySelection->AddIObject(myActor->getIO()); + } + busy = false; +} + +//================================================================================= +// function : onObjectSelectionChanged() +// purpose : Called when selection in 3D view or ObjectBrowser is changed +//================================================================================= +void SMESHGUI_GroupDlg::onObjectSelectionChanged() +{ + if (busy) return; + busy = true; + + int aNbSel = mySelection->IObjectCount(); + myElements->clearSelection(); + + if (myCurrentLineEdit) { + myCurrentLineEdit->setText("") ; + QString aString = ""; + if (aNbSel >= 1) { + if (aNbSel > 1) { + if (myCurrentLineEdit = mySubMeshLine) + aString = tr("SMESH_SUBMESH_SELECTED").arg(aNbSel); + else if (myCurrentLineEdit = myGroupLine) + aString = tr("SMESH_GROUP_SELECTED").arg(aNbSel); + } + else { + aString = mySelection->firstIObject()->getName(); + } + } + + myCurrentLineEdit->setText(aString) ; + myCurrentLineEdit->home( false ); + } + else { + if (aNbSel == 1) { + QString aListStr = ""; + int aNbItems = 0; + if (myTypeId == 0) { + aNbItems = mySMESHGUI->GetNameOfSelectedNodes(mySelection, aListStr); + } + else { + aNbItems = mySMESHGUI->GetNameOfSelectedElements(mySelection, aListStr); + } + if (aNbItems > 0) { + QStringList anElements = QStringList::split(" ", aListStr); + QListBoxItem* anItem = 0; + for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) { + anItem = myElements->findItem(*it, Qt::ExactMatch); + if (anItem) myElements->setSelected(anItem, true); + } + } + } + } + busy = false; +} + + +//================================================================================= +// function : onSelectSubMesh() +// purpose : Called when selection in 3D view or ObjectBrowser is changed +//================================================================================= +void SMESHGUI_GroupDlg::onSelectSubMesh(bool on) +{ + if (on) { + if (mySelectGroup->isChecked()) { + mySelectGroup->setChecked(false); + } + myCurrentLineEdit = mySubMeshLine; + setSelectionMode(4); + } + else { + mySubMeshLine->setText(""); + myCurrentLineEdit = 0; + if (myTypeId != -1) + setSelectionMode(myTypeId); + } + mySubMeshBtn->setEnabled(on); + mySubMeshLine->setEnabled(on); +} + +//================================================================================= +// function : (onSelectGroup) +// purpose : Called when selection in 3D view or ObjectBrowser is changed +//================================================================================= +void SMESHGUI_GroupDlg::onSelectGroup(bool on) +{ + if (on) { + if (mySelectSubMesh->isChecked()) { + mySelectSubMesh->setChecked(false); + } + myCurrentLineEdit = myGroupLine; + setSelectionMode(5); + } + else { + myGroupLine->setText(""); + myCurrentLineEdit = 0; + if (myTypeId != -1) + setSelectionMode(myTypeId); + } + myGroupBtn->setEnabled(on); + myGroupLine->setEnabled(on); +} + +//================================================================================= +// function : setCurrentSelection() +// purpose : +//================================================================================= +void SMESHGUI_GroupDlg::setCurrentSelection() +{ + QPushButton* send = (QPushButton*)sender(); + myCurrentLineEdit = 0; + if (send == mySubMeshBtn) { + myCurrentLineEdit = mySubMeshLine; + onObjectSelectionChanged(); + } + else if (send == myGroupBtn) { + myCurrentLineEdit = myGroupLine; + onObjectSelectionChanged(); + } +} + + +//================================================================================= +// function : setFilters() +// purpose : SLOT. Called when "Filter" button pressed. +//================================================================================= +void SMESHGUI_GroupDlg::setFilters() +{ + SMESH::ElementType aType = SMESH::ALL; + switch ( myTypeId ) + { + case 0 : aType = SMESH::NODE; break; + case 1 : aType = SMESH::EDGE; break; + case 2 : aType = SMESH::FACE; break; + case 3 : aType = SMESH::VOLUME; break; + default: return; + } + + if ( myFilterDlg == 0 ) + myFilterDlg = new SMESHGUI_FilterDlg( this, aType, true ); + else + myFilterDlg->Init( aType ); + + myFilterDlg->SetSelection( mySelection ); + myFilterDlg->SetMesh( myMesh ); + myFilterDlg->SetSourceWg( myElements ); + + if ( myFilterDlg->exec() != QDialog::Accepted ) + return; + + if ( mySelectSubMesh->isChecked() || mySelectGroup->isChecked() ) + { + mySelectionMode = myTypeId; + mySelectSubMesh->setChecked( false ); + mySelectGroup->setChecked( false ); + } +} + +//================================================================================= +// function : onAdd() +// purpose : +//================================================================================= +void SMESHGUI_GroupDlg::onAdd() +{ + int aNbSel = mySelection->IObjectCount(); + if (aNbSel == 0) return; + + busy = true; + + SMESH::ElementType aType = SMESH::ALL; + switch(myTypeId) { + case 0: aType = SMESH::NODE; break; + case 1: aType = SMESH::EDGE; break; + case 2: aType = SMESH::FACE; break; + case 3: aType = SMESH::VOLUME; break; + } + + if (myCurrentLineEdit == 0) { + if (aNbSel != 1) { busy = false; return; } + QString aListStr = ""; + int aNbItems = 0; + if (myTypeId == 0) { + aNbItems = mySMESHGUI->GetNameOfSelectedNodes(mySelection, aListStr); + } + else { + aNbItems = mySMESHGUI->GetNameOfSelectedElements(mySelection, aListStr); + } + if (aNbItems > 0) { + QStringList anElements = QStringList::split(" ", aListStr); + QListBoxItem* anItem = 0; + for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) { + anItem = myElements->findItem(*it, Qt::ExactMatch); + if (!anItem) { + anItem = new QListBoxText(*it); + myElements->insertItem(anItem); + } + myElements->setSelected(anItem, true); + } + } + } + else if (myCurrentLineEdit == mySubMeshLine) { + Standard_Boolean aRes; + SALOME_ListIteratorOfListIO anIt(mySelection->StoredIObjects()); + for (; anIt.More(); anIt.Next()) { + SMESH::SMESH_subMesh_var aSubMesh = mySMESHGUI->ConvertIOinSubMesh(anIt.Value(), aRes); + if (aRes && !aSubMesh->_is_nil()) { + // check if mesh is the same + if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) { + if (aType == SMESH::NODE) { + try { + SMESH::long_array_var anElements = aSubMesh->GetNodesId(); + int k = anElements->length(); + QListBoxItem* anItem = 0; + for (int i = 0; i < k; i++) { + QString aText = QString::number(anElements[i]); + anItem = myElements->findItem(aText, Qt::ExactMatch); + if (!anItem) { + anItem = new QListBoxText(aText); + myElements->insertItem(anItem); + } + myElements->setSelected(anItem, true); + } + } + catch (const SALOME::SALOME_Exception& ex) { + QtCatchCorbaException(ex); + } + } + else { + try { + SMESH::long_array_var anElements = aSubMesh->GetElementsId(); + int k = anElements->length(); + QListBoxItem* anItem = 0; + for (int i = 0; i < k; i++) { + QString aText = QString::number(anElements[i]); + anItem = myElements->findItem(aText, Qt::ExactMatch); + if (!anItem) { + anItem = new QListBoxText(aText); + myElements->insertItem(anItem); + } + myElements->setSelected(anItem, true); + } + } + catch (const SALOME::SALOME_Exception& ex) { + QtCatchCorbaException(ex); + } + } + } + } + } + mySelectSubMesh->setChecked(false); + busy = false; + onListSelectionChanged(); + } + else if (myCurrentLineEdit == myGroupLine) { + Standard_Boolean aRes; + SALOME_ListIteratorOfListIO anIt(mySelection->StoredIObjects()); + for (; anIt.More(); anIt.Next()) { + SMESH::SMESH_Group_var aGroup = mySMESHGUI->ConvertIOinSMESHGroup(anIt.Value(), aRes); + if (aRes && !aGroup->_is_nil()) { + // check if mesh is the same + if (aGroup->GetType() == aType && aGroup->GetMesh()->GetId() == myMesh->GetId()) { + SMESH::long_array_var anElements = aGroup->GetListOfID(); + int k = anElements->length(); + QListBoxItem* anItem = 0; + for (int i = 0; i < k; i++) { + QString aText = QString::number(anElements[i]); + anItem = myElements->findItem(aText, Qt::ExactMatch); + if (!anItem) { + anItem = new QListBoxText(aText); + myElements->insertItem(anItem); + } + myElements->setSelected(anItem, true); + } + } + } + } + mySelectGroup->setChecked(false); + busy = false; + onListSelectionChanged(); + } + busy = false; + // mySelection->ClearIObjects(); + updateButtons(); +} + +//================================================================================= +// function : onRemove() +// purpose : +//================================================================================= +void SMESHGUI_GroupDlg::onRemove() +{ + busy = true; + if (myCurrentLineEdit == 0) { + for (int i = myElements->count(); i > 0; i--) { + if (myElements->isSelected(i-1)) { + myElements->removeItem(i-1); + } + } + } + else { + int aNbSel = mySelection->IObjectCount(); + if (aNbSel == 0) { busy = false; return; } + + SMESH::ElementType aType = SMESH::ALL; + switch(myTypeId) { + case 0: aType = SMESH::NODE; break; + case 1: aType = SMESH::EDGE; break; + case 2: aType = SMESH::FACE; break; + case 3: aType = SMESH::VOLUME; break; + } + + if (myCurrentLineEdit == mySubMeshLine) { + Standard_Boolean aRes; + SALOME_ListIteratorOfListIO anIt(mySelection->StoredIObjects()); + for (; anIt.More(); anIt.Next()) { + SMESH::SMESH_subMesh_var aSubMesh = mySMESHGUI->ConvertIOinSubMesh(anIt.Value(), aRes); + if (aRes && !aSubMesh->_is_nil()) { + // check if mesh is the same + if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) { + if (aType == SMESH::NODE) { + try { + SMESH::long_array_var anElements = aSubMesh->GetNodesId(); + int k = anElements->length(); + QListBoxItem* anItem = 0; + for (int i = 0; i < k; i++) { + anItem = myElements->findItem(QString::number(anElements[i]), Qt::ExactMatch); + if (anItem) delete anItem; + } + } + catch (const SALOME::SALOME_Exception& ex) { + QtCatchCorbaException(ex); + } + } + else { + try { + SMESH::long_array_var anElements = aSubMesh->GetElementsId(); + int k = anElements->length(); + QListBoxItem* anItem = 0; + for (int i = 0; i < k; i++) { + anItem = myElements->findItem(QString::number(anElements[i]), Qt::ExactMatch); + if (anItem) delete anItem; + } + } + catch (const SALOME::SALOME_Exception& ex) { + QtCatchCorbaException(ex); + } + } + } + } + } + } + else if (myCurrentLineEdit == myGroupLine) { + Standard_Boolean aRes; + SALOME_ListIteratorOfListIO anIt(mySelection->StoredIObjects()); + for (; anIt.More(); anIt.Next()) { + SMESH::SMESH_Group_var aGroup = mySMESHGUI->ConvertIOinSMESHGroup(anIt.Value(), aRes); + if (aRes && !aGroup->_is_nil()) { + // check if mesh is the same + if (aGroup->GetType() == aType && aGroup->GetMesh()->GetId() == myMesh->GetId()) { + SMESH::long_array_var anElements = aGroup->GetListOfID(); + int k = anElements->length(); + QListBoxItem* anItem = 0; + for (int i = 0; i < k; i++) { + anItem = myElements->findItem(QString::number(anElements[i]), Qt::ExactMatch); + if (anItem) delete anItem; + } + } + } + } + } + } + busy = false; + updateButtons(); +} + +//================================================================================= +// function : onSort() +// purpose : +//================================================================================= +void SMESHGUI_GroupDlg::onSort() +{ + // PAL5412: sorts items in ascending by "string" value + // myElements->sort(true); + // myElements->update(); + int i, k = myElements->count(); + if (k > 0) { + busy = true; + QStringList aSelected; + std::vector anArray(k); + // QMemArray anArray(k); + QListBoxItem* anItem; + // fill the array + for (anItem = myElements->firstItem(), i = 0; anItem != 0; anItem = anItem->next(), i++) { + anArray[i] = anItem->text().toInt(); + if (anItem->isSelected()) + aSelected.append(anItem->text()); + } + // sort & update list + std::sort(anArray.begin(), anArray.end()); + // anArray.sort(); + myElements->clear(); + for (i = 0; i < k; i++) { + myElements->insertItem(QString::number(anArray[i])); + } + for (QStringList::iterator it = aSelected.begin(); it != aSelected.end(); ++it) { + anItem = myElements->findItem(*it, Qt::ExactMatch); + if (anItem) myElements->setSelected(anItem, true); + } + busy = false; + } +} + +//================================================================================= +// function : closeEvent() +// purpose : +//================================================================================= +void SMESHGUI_GroupDlg::closeEvent( QCloseEvent* e ) +{ + QAD_StudyFrame* aStudyFrame = mySMESHGUI->GetActiveStudy()->getActiveStudyFrame(); + if (aStudyFrame->getTypeView() == VIEW_VTK) { + mySMESHGUI->SetPickable(); + if (mySelectionMode == 0) + mySMESHGUI->EraseSimulationActors(); + + // remove filters from viewer + VTKViewer_InteractorStyleSALOME* aStyle = ((VTKViewer_ViewFrame*)aStudyFrame->getRightFrame()->getViewFrame())->getRWInteractor()->GetInteractorStyleSALOME(); + aStyle->RemoveEdgeFilter(); + aStyle->RemoveFaceFilter(); + + } + + mySelection->ClearIObjects(); + QAD_Application::getDesktop()->SetSelectionMode(ActorSelection); + mySelection->ClearFilters(); + mySMESHGUI->ResetState(); + + QDialog::closeEvent( e ); +} diff --git a/src/SMESHGUI/SMESHGUI_GroupDlg.h b/src/SMESHGUI/SMESHGUI_GroupDlg.h new file mode 100644 index 000000000..b18abdfd1 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_GroupDlg.h @@ -0,0 +1,132 @@ +// SMESH SMESHGUI : GUI for SMESH component +// +// Copyright (C) 2003 CEA +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESHGUI_GroupDlg.h +// Author : Natalia KOPNOVA +// Module : SMESH +// $Header$ + +#ifndef DIALOGBOX_GROUP_H +#define DIALOGBOX_GROUP_H + +#include "SALOME_Selection.h" +#include "SMESH_TypeFilter.hxx" + +// QT Includes +#include +#include + +// IDL Headers +#include +#include CORBA_SERVER_HEADER(SMESH_Mesh) +#include CORBA_SERVER_HEADER(SMESH_Group) + +class QLineEdit; +class QButtonGroup; +class QListBox; +class QPushButton; +class QCheckBox; +class SMESHGUI; +class SMESH_Actor; +class SMESHGUI_FilterDlg; + +//================================================================================= +// class : SMESHGUI_GroupDlg +// purpose : +//================================================================================= +class SMESHGUI_GroupDlg : public QDialog +{ + Q_OBJECT + +public: + SMESHGUI_GroupDlg( QWidget* parent = 0, const char* name = 0, SALOME_Selection* theSel = 0, + SMESH::SMESH_Mesh_ptr theMesh = SMESH::SMESH_Mesh::_nil(), + bool modal = FALSE, WFlags fl = 0 ); + SMESHGUI_GroupDlg( QWidget* parent, const char* name, SALOME_Selection* theSel, + SMESH::SMESH_Group_ptr theGroup, bool modal = FALSE, WFlags fl = 0 ); + ~SMESHGUI_GroupDlg(); + +public slots: + + void onAdd(); + void onRemove(); + + +private slots: + + void onTypeChanged(int id); + + void onOK(); + void onClose(); + bool onApply(); + + void onListSelectionChanged(); + void onObjectSelectionChanged(); + + void onSelectSubMesh(bool on); + void onSelectGroup(bool on); + void setCurrentSelection(); + + void setFilters(); + void onSort(); + + void onNameChanged(const QString& text); + +private: + void initDialog(SALOME_Selection* theSel, bool create); + void init(SMESH::SMESH_Mesh_ptr theMesh); + void init(SMESH::SMESH_Group_ptr theGroup); + void closeEvent(QCloseEvent* e); + void setSelectionMode(int theMode); + void updateButtons(); + + SMESHGUI* mySMESHGUI ; /* Current SMESHGUI object */ + SALOME_Selection* mySelection ; /* User shape selection */ + SMESH_Actor* myActor; /* Current mesh actor */ + int myTypeId ; /* Current type id = radio button id */ + QLineEdit* myCurrentLineEdit; /* Current LineEdit */ + + QButtonGroup* myTypeGroup; + QLineEdit* myName; + QListBox* myElements; + QPushButton* myFilter; + + QCheckBox* mySelectSubMesh; + QPushButton* mySubMeshBtn; + QLineEdit* mySubMeshLine; + + QCheckBox* mySelectGroup; + QPushButton* myGroupBtn; + QLineEdit* myGroupLine; + + SMESH::SMESH_Mesh_var myMesh; + SMESH::SMESH_Group_var myGroup; + QValueList myIdList; + + int mySelectionMode; + Handle(SMESH_TypeFilter) mySubMeshFilter; + Handle(SMESH_TypeFilter) myGroupFilter; + + SMESHGUI_FilterDlg* myFilterDlg; +}; + +#endif // DIALOGBOX_GROUP_H diff --git a/src/SMESHGUI/SMESHGUI_Hypotheses.h b/src/SMESHGUI/SMESHGUI_Hypotheses.h new file mode 100644 index 000000000..932226296 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_Hypotheses.h @@ -0,0 +1,74 @@ +// SMESH SMESHGUI : GUI for SMESH component +// +// Copyright (C) 2003 CEA +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESHGUI_Hypotheses.h +// Author : Julia DOROVSKIKH +// Module : SMESH +// $Header$ + +#ifndef SMESHGUI_Hypotheses_HeaderFile +#define SMESHGUI_Hypotheses_HeaderFile + +#include CORBA_SERVER_HEADER(SMESH_Hypothesis) + +// QT Includes +#include +#include + +//================================================================================= +// class : SMESHGUI_GenericHypothesisCreator +// purpose : +//================================================================================= +class SMESHGUI_GenericHypothesisCreator +{ + public: + virtual void CreateHypothesis (const bool isAlgo, QWidget* parent) = 0; + virtual void EditHypothesis (SMESH::SMESH_Hypothesis_ptr theHyp) = 0; +}; + +//================================================================================= +// class : HypothesisData +// purpose : +//================================================================================= +class HypothesisData +{ + public: + HypothesisData (const QString& aPluginName, + const QString& aServerLibName, + const QString& aClientLibName, + const QString& aLabel, + const QString& anIconId) : + PluginName(aPluginName), + ServerLibName(aServerLibName), + ClientLibName(aClientLibName), + Label(aLabel), + IconId(anIconId) + {}; + + QString PluginName; + QString ServerLibName; + QString ClientLibName; + QString Label; + QString IconId; +}; + +#endif diff --git a/src/SMESHGUI/SMESHGUI_InitMeshDlg.cxx b/src/SMESHGUI/SMESHGUI_InitMeshDlg.cxx index 4261740b3..ac34a76c7 100644 --- a/src/SMESHGUI/SMESHGUI_InitMeshDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_InitMeshDlg.cxx @@ -33,23 +33,20 @@ using namespace std; #include "QAD_Application.h" #include "QAD_Desktop.h" +#include "QAD_MessageBox.h" +#include "QAD_WaitCursor.h" +#include "QAD_Operation.h" + #include "utilities.h" // QT Includes -#include #include #include #include #include -#include #include -#include -#include -#include -#include #include - //================================================================================= // class : SMESHGUI_InitMeshDlg() // purpose : Constructs a SMESHGUI_InitMeshDlg which is a child of 'parent', with the @@ -58,135 +55,88 @@ using namespace std; // TRUE to construct a modal dialog. //================================================================================= SMESHGUI_InitMeshDlg::SMESHGUI_InitMeshDlg( QWidget* parent, const char* name, SALOME_Selection* Sel, bool modal, WFlags fl ) - : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ) + : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose ) { - QPixmap image1(QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr("ICON_DLG_INIT_MESH"))); QPixmap image0(QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr("ICON_SELECT"))); if ( !name ) setName( "SMESHGUI_InitMeshDlg" ); - resize( 303, 175 ); setCaption( tr( "SMESH_INIT_MESH" ) ); setSizeGripEnabled( TRUE ); - SMESHGUI_InitMeshDlgLayout = new QGridLayout( this ); + QGridLayout* SMESHGUI_InitMeshDlgLayout = new QGridLayout( this ); SMESHGUI_InitMeshDlgLayout->setSpacing( 6 ); SMESHGUI_InitMeshDlgLayout->setMargin( 11 ); /***************************************************************/ - GroupConstructors = new QButtonGroup( this, "GroupConstructors" ); - GroupConstructors->setTitle( tr( "SMESH_INIT" ) ); - GroupConstructors->setExclusive( TRUE ); - GroupConstructors->setColumnLayout(0, Qt::Vertical ); - GroupConstructors->layout()->setSpacing( 0 ); - GroupConstructors->layout()->setMargin( 0 ); - GroupConstructorsLayout = new QGridLayout( GroupConstructors->layout() ); - GroupConstructorsLayout->setAlignment( Qt::AlignTop ); - GroupConstructorsLayout->setSpacing( 6 ); - GroupConstructorsLayout->setMargin( 11 ); - Constructor1 = new QRadioButton( GroupConstructors, "Constructor1" ); - Constructor1->setText( tr( "" ) ); - Constructor1->setPixmap( image1 ); - Constructor1->setChecked( TRUE ); - Constructor1->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, Constructor1->sizePolicy().hasHeightForWidth() ) ); - Constructor1->setMinimumSize( QSize( 50, 0 ) ); - GroupConstructorsLayout->addWidget( Constructor1, 0, 0 ); - QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); - GroupConstructorsLayout->addItem( spacer, 0, 1 ); - SMESHGUI_InitMeshDlgLayout->addWidget( GroupConstructors, 0, 0 ); - - /***************************************************************/ - GroupButtons = new QGroupBox( this, "GroupButtons" ); - GroupButtons->setGeometry( QRect( 10, 10, 281, 48 ) ); - GroupButtons->setTitle( tr( "" ) ); - GroupButtons->setColumnLayout(0, Qt::Vertical ); - GroupButtons->layout()->setSpacing( 0 ); - GroupButtons->layout()->setMargin( 0 ); - GroupButtonsLayout = new QGridLayout( GroupButtons->layout() ); - GroupButtonsLayout->setAlignment( Qt::AlignTop ); - GroupButtonsLayout->setSpacing( 6 ); - GroupButtonsLayout->setMargin( 11 ); - buttonCancel = new QPushButton( GroupButtons, "buttonCancel" ); - buttonCancel->setText( tr( "SMESH_BUT_CLOSE" ) ); - buttonCancel->setAutoDefault( TRUE ); - GroupButtonsLayout->addWidget( buttonCancel, 0, 3 ); - buttonApply = new QPushButton( GroupButtons, "buttonApply" ); - buttonApply->setText( tr( "SMESH_BUT_APPLY" ) ); - buttonApply->setAutoDefault( TRUE ); - GroupButtonsLayout->addWidget( buttonApply, 0, 1 ); - QSpacerItem* spacer_9 = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); - GroupButtonsLayout->addItem( spacer_9, 0, 2 ); - buttonOk = new QPushButton( GroupButtons, "buttonOk" ); - buttonOk->setText( tr( "SMESH_BUT_OK" ) ); - buttonOk->setAutoDefault( TRUE ); - buttonOk->setDefault( TRUE ); - GroupButtonsLayout->addWidget( buttonOk, 0, 0 ); - SMESHGUI_InitMeshDlgLayout->addWidget( GroupButtons, 2, 0 ); - - /***************************************************************/ - GroupC1 = new QGroupBox( this, "GroupC1" ); - GroupC1->setTitle( tr( "SMESH_ARGUMENTS" ) ); - GroupC1->setMinimumSize( QSize( 0, 0 ) ); - GroupC1->setFrameShape( QGroupBox::Box ); - GroupC1->setFrameShadow( QGroupBox::Sunken ); + GroupC1 = new QGroupBox( tr( "SMESH_ARGUMENTS" ), this, "GroupC1" ); GroupC1->setColumnLayout(0, Qt::Vertical ); GroupC1->layout()->setSpacing( 0 ); GroupC1->layout()->setMargin( 0 ); - GroupC1Layout = new QGridLayout( GroupC1->layout() ); + QGridLayout* GroupC1Layout = new QGridLayout( GroupC1->layout() ); GroupC1Layout->setAlignment( Qt::AlignTop ); GroupC1Layout->setSpacing( 6 ); GroupC1Layout->setMargin( 11 ); - TextLabelC1A1 = new QLabel( GroupC1, "TextLabelC1A1" ); - TextLabelC1A1->setText( tr( "SMESH_OBJECT_GEOM" ) ); - TextLabelC1A1->setMinimumSize( QSize( 50, 0 ) ); - TextLabelC1A1->setFrameShape( QLabel::NoFrame ); - TextLabelC1A1->setFrameShadow( QLabel::Plain ); - GroupC1Layout->addWidget( TextLabelC1A1, 0, 0 ); + TextLabel_NameMesh = new QLabel( tr( "SMESH_NAME" ), GroupC1, "TextLabel_NameMesh" ); + GroupC1Layout->addWidget( TextLabel_NameMesh, 0, 0 ); + LineEdit_NameMesh = new QLineEdit( GroupC1, "LineEdit_NameMesh" ); + GroupC1Layout->addWidget( LineEdit_NameMesh, 0, 2 ); + + TextLabelC1A1 = new QLabel( tr( "SMESH_OBJECT_GEOM" ), GroupC1, "TextLabelC1A1" ); + GroupC1Layout->addWidget( TextLabelC1A1, 1, 0 ); SelectButtonC1A1 = new QPushButton( GroupC1, "SelectButtonC1A1" ); - SelectButtonC1A1->setText( tr( "" ) ); SelectButtonC1A1->setPixmap( image0 ); SelectButtonC1A1->setToggleButton( FALSE ); - GroupC1Layout->addWidget( SelectButtonC1A1, 0, 1 ); + GroupC1Layout->addWidget( SelectButtonC1A1, 1, 1 ); LineEditC1A1 = new QLineEdit( GroupC1, "LineEditC1A1" ); - GroupC1Layout->addWidget( LineEditC1A1, 0, 2 ); + GroupC1Layout->addWidget( LineEditC1A1, 1, 2 ); - TextLabel_NameMesh = new QLabel( GroupC1, "TextLabel_NameMesh" ); - TextLabel_NameMesh->setText( tr( "SMESH_NAME" ) ); - GroupC1Layout->addWidget( TextLabel_NameMesh, 1, 0 ); - LineEdit_NameMesh = new QLineEdit( GroupC1, "LineEdit_NameMesh" ); - GroupC1Layout->addWidget( LineEdit_NameMesh, 1, 2 ); - - TextLabelC1A1Hyp = new QLabel( GroupC1, "TextLabelC1A1Hyp" ); - TextLabelC1A1Hyp->setText( tr( "SMESH_OBJECT_HYPOTHESIS" ) ); - TextLabelC1A1Hyp->setMinimumSize( QSize( 50, 0 ) ); - TextLabelC1A1Hyp->setFrameShape( QLabel::NoFrame ); - TextLabelC1A1Hyp->setFrameShadow( QLabel::Plain ); + TextLabelC1A1Hyp = new QLabel( tr( "SMESH_OBJECT_HYPOTHESIS" ), GroupC1, "TextLabelC1A1Hyp" ); GroupC1Layout->addWidget( TextLabelC1A1Hyp, 2, 0 ); SelectButtonC1A1Hyp = new QPushButton( GroupC1, "SelectButtonC1A1Hyp" ); - SelectButtonC1A1Hyp->setText( tr( "" ) ); SelectButtonC1A1Hyp->setPixmap( image0 ); GroupC1Layout->addWidget( SelectButtonC1A1Hyp, 2, 1 ); LineEditC1A1Hyp = new QLineEdit( GroupC1, "LineEditC1A1Hyp" ); - LineEditC1A1Hyp->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)3, (QSizePolicy::SizeType)0, LineEditC1A1Hyp->sizePolicy().hasHeightForWidth() ) ); GroupC1Layout->addWidget( LineEditC1A1Hyp, 2, 2 ); - TextLabelC1A1Algo = new QLabel( GroupC1, "TextLabelC1A1Algo" ); - TextLabelC1A1Algo->setText( tr( "SMESH_OBJECT_ALGORITHM" ) ); - TextLabelC1A1Algo->setMinimumSize( QSize( 50, 0 ) ); - TextLabelC1A1Algo->setFrameShape( QLabel::NoFrame ); - TextLabelC1A1Algo->setFrameShadow( QLabel::Plain ); + TextLabelC1A1Algo = new QLabel( tr( "SMESH_OBJECT_ALGORITHM" ), GroupC1, "TextLabelC1A1Algo" ); GroupC1Layout->addWidget( TextLabelC1A1Algo, 3, 0 ); SelectButtonC1A1Algo = new QPushButton( GroupC1, "SelectButtonC1A1Algo" ); - SelectButtonC1A1Algo->setText( tr( "" ) ); SelectButtonC1A1Algo->setPixmap( image0 ); GroupC1Layout->addWidget( SelectButtonC1A1Algo, 3, 1 ); LineEditC1A1Algo = new QLineEdit( GroupC1, "LineEditC1A1Algo" ); - LineEditC1A1Algo->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)3, (QSizePolicy::SizeType)0, LineEditC1A1Algo->sizePolicy().hasHeightForWidth() ) ); GroupC1Layout->addWidget( LineEditC1A1Algo, 3, 2 ); SMESHGUI_InitMeshDlgLayout->addWidget( GroupC1, 1, 0 ); + /***************************************************************/ + GroupButtons = new QGroupBox( this, "GroupButtons" ); + GroupButtons->setColumnLayout(0, Qt::Vertical ); + GroupButtons->layout()->setSpacing( 0 ); + GroupButtons->layout()->setMargin( 0 ); + QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() ); + GroupButtonsLayout->setAlignment( Qt::AlignTop ); + GroupButtonsLayout->setSpacing( 6 ); + GroupButtonsLayout->setMargin( 11 ); + + buttonOk = new QPushButton( tr( "SMESH_BUT_OK" ), GroupButtons, "buttonOk" ); + buttonOk->setAutoDefault( TRUE ); + buttonOk->setDefault( TRUE ); + GroupButtonsLayout->addWidget( buttonOk, 0, 0 ); + + buttonApply = new QPushButton( tr( "SMESH_BUT_APPLY" ), GroupButtons, "buttonApply" ); + buttonApply->setAutoDefault( TRUE ); + GroupButtonsLayout->addWidget( buttonApply, 0, 1 ); + + GroupButtonsLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 2 ); + + buttonCancel = new QPushButton( tr( "SMESH_BUT_CLOSE" ), GroupButtons, "buttonCancel" ); + buttonCancel->setAutoDefault( TRUE ); + GroupButtonsLayout->addWidget( buttonCancel, 0, 3 ); + + SMESHGUI_InitMeshDlgLayout->addWidget( GroupButtons, 2, 0 ); - Init(Sel) ; + /***************************************************************/ + Init( Sel ) ; } @@ -206,108 +156,118 @@ SMESHGUI_InitMeshDlg::~SMESHGUI_InitMeshDlg() //================================================================================= void SMESHGUI_InitMeshDlg::Init( SALOME_Selection* Sel ) { - GroupC1->show(); - myConstructorId = 0 ; - Constructor1->setChecked( TRUE ); - myEditCurrentArgument = LineEditC1A1 ; mySelection = Sel; mySMESHGUI = SMESHGUI::GetSMESHGUI() ; mySMESHGUI->SetActiveDialogBox( (QDialog*)this ) ; - myGeomFilter = new SALOME_TypeFilter( "GEOM" ); - myAlgorithmFilter = new SMESH_TypeFilter( ALGORITHM ); + myGeomFilter = new SALOME_TypeFilter( "GEOM" ); + myAlgorithmFilter = new SMESH_TypeFilter( ALGORITHM ); myHypothesisFilter = new SMESH_TypeFilter( HYPOTHESIS ); - myNameMesh = "Mesh"; - /* signals and slots connections */ - connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) ); - connect( buttonApply, SIGNAL( clicked() ), this, SLOT(ClickOnApply() ) ); + connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) ); + connect( buttonApply, SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) ); connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) ) ; - connect( GroupConstructors, SIGNAL(clicked(int) ), SLOT( ConstructorsClicked(int) ) ); - connect( SelectButtonC1A1, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ; - connect( LineEdit_NameMesh, SIGNAL (textChanged(const QString&) ), this, SLOT( TextChangedInLineEdit(const QString&) ) ) ; - - connect( SelectButtonC1A1Hyp, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ; + connect( SelectButtonC1A1, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ; + connect( SelectButtonC1A1Hyp, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ; connect( SelectButtonC1A1Algo, SIGNAL (clicked() ), this, SLOT( SetEditCurrentArgument() ) ) ; - connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) ); - connect( mySMESHGUI, SIGNAL ( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ; - connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) ) ; + connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) ); + connect( mySMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ; + connect( mySMESHGUI, SIGNAL( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) ) ; int x, y ; mySMESHGUI->DefineDlgPosition( this, x, y ) ; this->move( x, y ) ; this->show() ; - return ; -} + LineEdit_NameMesh->setText( tr( "SMESH_OBJECT_MESH" ) ); + LineEdit_NameMesh->setFocus() ; + myEditCurrentArgument = LineEditC1A1 ; + mySelection->ClearFilters() ; + mySelection->AddFilter( myGeomFilter ) ; + SelectionIntoArgument(); -//================================================================================= -// function : ConstructorsClicked() -// purpose : Radio button management -//================================================================================= -void SMESHGUI_InitMeshDlg::ConstructorsClicked(int constructorId) -{ - return ; + UpdateControlState(); } + //================================================================================= // function : ClickOnOk() // purpose : //================================================================================= void SMESHGUI_InitMeshDlg::ClickOnOk() { - this->ClickOnApply() ; - this->ClickOnCancel() ; - - return ; + if ( this->ClickOnApply() ) + this->ClickOnCancel() ; } //================================================================================= // function : ClickOnApply() // purpose : //================================================================================= -void SMESHGUI_InitMeshDlg::ClickOnApply() +bool SMESHGUI_InitMeshDlg::ClickOnApply() { - switch(myConstructorId) - { - case 0 : - { - MESSAGE ( " myNameMesh " << myNameMesh.isEmpty() ) - MESSAGE ( " myGeomShape " << myGeomShape->_is_nil() ) - if ( !myNameMesh.isEmpty() && !myNameMesh.isNull() && !myGeomShape->_is_nil() ) - myMesh = mySMESHGUI->InitMesh( myGeomShape, myNameMesh ) ; - - MESSAGE ( " myMesh " << myMesh->_is_nil() ) - MESSAGE ( " myOkHypothesis " ) - MESSAGE ( " myOkAlgorithm " ) - if( myOkHypothesis && !myMesh->_is_nil() ) { - SALOME_ListIteratorOfListIO It( HypoList ); - for(;It.More();It.Next()) { - Handle(SALOME_InteractiveObject) IObject = It.Value(); - Standard_Boolean testResult; - myHypothesis = mySMESHGUI->ConvertIOinSMESHHypothesis(IObject, testResult) ; - if( testResult ) - mySMESHGUI->AddHypothesisOnMesh(myMesh, myHypothesis) ; + QString myNameMesh = LineEdit_NameMesh->text().stripWhiteSpace(); + if ( myNameMesh.isEmpty() ) { + QAD_MessageBox::warn1( this, tr( "SMESH_WRN_WARNING" ), tr( "SMESH_WRN_EMPTY_NAME" ), tr( "SMESH_BUT_OK" ) ); + return false; + } + + if ( myGeomShape->_is_nil() || !HypoList.count() || !AlgoList.count() ) + return false; + + QAD_WaitCursor wc; + + QAD_Operation* op = new QAD_Operation( mySMESHGUI->GetActiveStudy() ); + + // start transaction + op->start(); + + // create mesh + SMESH::SMESH_Mesh_var aMesh = mySMESHGUI->InitMesh( myGeomShape, myNameMesh ) ; + + if ( !aMesh->_is_nil() ) { + // assign hypotheses + for( int i = 0; i < HypoList.count(); i++ ) { + SALOMEDS::SObject_var aHypSO = mySMESHGUI->GetStudy()->FindObjectID( HypoList[i] ); + if ( !aHypSO->_is_nil() ) { + CORBA::Object_var anObject = aHypSO->GetObject(); + if ( !CORBA::is_nil( anObject ) ) { + SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( anObject ); + if ( !aHyp->_is_nil() ) { + if ( !mySMESHGUI->AddHypothesisOnMesh( aMesh, aHyp ) ) { + // abort transaction + op->abort(); + return false; + } } } - - if( myOkAlgorithm && !myMesh->_is_nil() ) { - SALOME_ListIteratorOfListIO It( AlgoList ); - for(;It.More();It.Next()) { - Handle(SALOME_InteractiveObject) IObject = It.Value(); - Standard_Boolean testResult; - myAlgorithm = mySMESHGUI->ConvertIOinSMESHHypothesis(IObject, testResult) ; - if( testResult ) - mySMESHGUI->AddAlgorithmOnMesh(myMesh, myAlgorithm) ; + } + } + // assign algorithms + for( int i = 0; i < AlgoList.count(); i++ ) { + SALOMEDS::SObject_var aHypSO = mySMESHGUI->GetStudy()->FindObjectID( AlgoList[i] ); + if ( !aHypSO->_is_nil() ) { + CORBA::Object_var anObject = aHypSO->GetObject(); + if ( !CORBA::is_nil( anObject ) ) { + SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( anObject ); + if ( !aHyp->_is_nil() ) { + if ( !mySMESHGUI->AddAlgorithmOnMesh( aMesh, aHyp ) ) { + // abort transaction + op->abort(); + return false; + } } } - break ; } } + } + // commit transaction + op->finish(); + return true; } @@ -317,11 +277,7 @@ void SMESHGUI_InitMeshDlg::ClickOnApply() //================================================================================= void SMESHGUI_InitMeshDlg::ClickOnCancel() { - mySelection->ClearFilters() ; - disconnect( mySelection, 0, this, 0 ); - mySMESHGUI->ResetState() ; - reject() ; - return ; + close(); } @@ -331,61 +287,60 @@ void SMESHGUI_InitMeshDlg::ClickOnCancel() //================================================================================= void SMESHGUI_InitMeshDlg::SelectionIntoArgument() { - myEditCurrentArgument->setText("") ; QString aString = ""; + int nbSel = mySMESHGUI->GetNameOfSelectedIObjects(mySelection, aString) ; + if ( myEditCurrentArgument == LineEditC1A1 ) { + // geom shape if ( nbSel != 1 ) { - myOkHypothesis = false; - myOkAlgorithm = false; myGeomShape = GEOM::GEOM_Shape::_nil(); - return ; - } else { + aString = ""; + } + else { Standard_Boolean testResult ; Handle(SALOME_InteractiveObject) IO = mySelection->firstIObject() ; myGeomShape = mySMESHGUI->ConvertIOinGEOMShape(IO, testResult) ; if( !testResult ) { - myOkHypothesis = false; - myOkAlgorithm = false; - return ; + myGeomShape = GEOM::GEOM_Shape::_nil(); + aString = ""; } } } else if ( myEditCurrentArgument == LineEditC1A1Hyp ) { + // hypotheses + HypoList.clear(); if ( nbSel >= 1 ) { - HypoList.Clear(); SALOME_ListIteratorOfListIO Itinit( mySelection->StoredIObjects() ); - for (; Itinit.More(); Itinit.Next()) { - HypoList.Append(Itinit.Value()); + for ( ; Itinit.More(); Itinit.Next() ) { + HypoList.append( Itinit.Value()->getEntry() ); } - myOkHypothesis = true ; - if (nbSel > 1) - aString = tr("%1 Hypothesis").arg(nbSel) ; - LineEditC1A1Hyp->setText(aString) ; + if ( nbSel > 1 ) + aString = tr( "%1 Hypothesis" ).arg( nbSel ) ; } else { - myOkHypothesis = false ; - return ; + aString = ""; } - } else if ( myEditCurrentArgument == LineEditC1A1Algo ) { + } + else if ( myEditCurrentArgument == LineEditC1A1Algo ) { + // algorithms + AlgoList.clear(); if ( nbSel >= 1 ) { - AlgoList.Clear(); SALOME_ListIteratorOfListIO Itinit( mySelection->StoredIObjects() ); - for (; Itinit.More(); Itinit.Next()) { - AlgoList.Append(Itinit.Value()); + for ( ; Itinit.More(); Itinit.Next() ) { + AlgoList.append( Itinit.Value()->getEntry() ); } - myOkAlgorithm = true ; - if (nbSel > 1) - aString = tr("%1 Algorithms").arg(nbSel) ; - LineEditC1A1Algo->setText(aString) ; + if ( nbSel > 1 ) + aString = tr( "%1 Algorithms" ).arg( nbSel ) ; } else { - myOkAlgorithm = false ; - return ; + aString = ""; } } myEditCurrentArgument->setText(aString) ; + + UpdateControlState(); } @@ -396,31 +351,23 @@ void SMESHGUI_InitMeshDlg::SelectionIntoArgument() void SMESHGUI_InitMeshDlg::SetEditCurrentArgument() { QPushButton* send = (QPushButton*)sender(); - switch (myConstructorId) - { - case 0: /* default constructor */ - { - if(send == SelectButtonC1A1) { - LineEditC1A1->setFocus() ; - myEditCurrentArgument = LineEditC1A1; - mySelection->ClearFilters() ; - mySelection->AddFilter(myGeomFilter) ; - } else if( send == SelectButtonC1A1Hyp ) { - LineEditC1A1Hyp->setFocus() ; - myEditCurrentArgument = LineEditC1A1Hyp ; - mySelection->ClearFilters() ; - mySelection->AddFilter(myHypothesisFilter) ; - } else if( send == SelectButtonC1A1Algo ) { - LineEditC1A1Algo->setFocus() ; - myEditCurrentArgument = LineEditC1A1Algo ; - mySelection->ClearFilters() ; - mySelection->AddFilter(myAlgorithmFilter) ; - } - SelectionIntoArgument() ; - break; - } - } - return ; + if(send == SelectButtonC1A1) { + LineEditC1A1->setFocus() ; + myEditCurrentArgument = LineEditC1A1; + mySelection->ClearFilters() ; + mySelection->AddFilter(myGeomFilter) ; + } else if( send == SelectButtonC1A1Hyp ) { + LineEditC1A1Hyp->setFocus() ; + myEditCurrentArgument = LineEditC1A1Hyp ; + mySelection->ClearFilters() ; + mySelection->AddFilter(myHypothesisFilter) ; + } else if( send == SelectButtonC1A1Algo ) { + LineEditC1A1Algo->setFocus() ; + myEditCurrentArgument = LineEditC1A1Algo ; + mySelection->ClearFilters() ; + mySelection->AddFilter(myAlgorithmFilter) ; + } + SelectionIntoArgument() ; } //================================================================================= @@ -429,9 +376,8 @@ void SMESHGUI_InitMeshDlg::SetEditCurrentArgument() //================================================================================= void SMESHGUI_InitMeshDlg::DeactivateActiveDialog() { - if ( GroupConstructors->isEnabled() ) { + if ( GroupC1->isEnabled() ) { disconnect( mySelection, 0, this, 0 ); - GroupConstructors->setEnabled(false) ; GroupC1->setEnabled(false) ; GroupButtons->setEnabled(false) ; } @@ -445,11 +391,9 @@ void SMESHGUI_InitMeshDlg::DeactivateActiveDialog() void SMESHGUI_InitMeshDlg::ActivateThisDialog() { mySMESHGUI->EmitSignalDeactivateDialog() ; - GroupConstructors->setEnabled(true) ; GroupC1->setEnabled(true) ; GroupButtons->setEnabled(true) ; connect ( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) ); - return ; } @@ -459,10 +403,8 @@ void SMESHGUI_InitMeshDlg::ActivateThisDialog() //================================================================================= void SMESHGUI_InitMeshDlg::enterEvent(QEvent* e) { - if ( GroupConstructors->isEnabled() ) - return ; - ActivateThisDialog() ; - return ; + if ( !GroupC1->isEnabled() ) + ActivateThisDialog() ; } @@ -472,21 +414,25 @@ void SMESHGUI_InitMeshDlg::enterEvent(QEvent* e) //================================================================================= void SMESHGUI_InitMeshDlg::closeEvent( QCloseEvent* e ) { - this->ClickOnCancel() ; - return ; + disconnect( mySelection, 0, this, 0 ); + mySMESHGUI->ResetState() ; + mySelection->ClearFilters() ; + QDialog::closeEvent( e ); } //================================================================================= -// function : TextChangedInLineEdit() +// function : UpdateControlState() // purpose : //================================================================================= -void SMESHGUI_InitMeshDlg::TextChangedInLineEdit(const QString& newText) -{ - QLineEdit* send = (QLineEdit*)sender(); - QString newT = strdup(newText) ; - - if (send == LineEdit_NameMesh) { - myNameMesh = newText; - } - return ; +void SMESHGUI_InitMeshDlg::UpdateControlState() +{ + bool isEnabled = ( !myGeomShape->_is_nil() && HypoList.count() && AlgoList.count() ); + + buttonOk ->setEnabled( isEnabled ); + buttonApply->setEnabled( isEnabled ); } + + + + + diff --git a/src/SMESHGUI/SMESHGUI_InitMeshDlg.h b/src/SMESHGUI/SMESHGUI_InitMeshDlg.h index 9d934183a..ec04b7942 100644 --- a/src/SMESHGUI/SMESHGUI_InitMeshDlg.h +++ b/src/SMESHGUI/SMESHGUI_InitMeshDlg.h @@ -34,8 +34,8 @@ #include "SMESH_TypeFilter.hxx" // QT Includes -#include #include +#include // IDL Headers #include @@ -43,18 +43,12 @@ #include CORBA_SERVER_HEADER(GEOM_Shape) #include CORBA_SERVER_HEADER(SMESH_Gen) -class QVBoxLayout; -class QHBoxLayout; -class QGridLayout; -class QButtonGroup; class QGroupBox; class QLabel; class QLineEdit; class QPushButton; -class QRadioButton; class SMESHGUI; - //================================================================================= // class : SMESHGUI_InitMeshDlg // purpose : @@ -67,42 +61,34 @@ public: SMESHGUI_InitMeshDlg( QWidget* parent = 0, const char* name = 0, SALOME_Selection* Sel = 0, bool modal = FALSE, WFlags fl = 0 ); ~SMESHGUI_InitMeshDlg(); -private: - - void Init( SALOME_Selection* Sel ) ; +protected: void closeEvent( QCloseEvent* e ) ; void enterEvent ( QEvent * ) ; +private: + void Init( SALOME_Selection* Sel ) ; + + void UpdateControlState(); + +private: SMESHGUI* mySMESHGUI ; SALOME_Selection* mySelection ; - GEOM::GEOM_Shape_var myGeomShape ; - int myConstructorId ; + GEOM::GEOM_Shape_var myGeomShape ; QLineEdit* myEditCurrentArgument; - QString myNameMesh ; - Handle(SALOME_TypeFilter) myGeomFilter; Handle(SMESH_TypeFilter) myHypothesisFilter; Handle(SMESH_TypeFilter) myAlgorithmFilter; - SALOME_ListIO HypoList; - SALOME_ListIO AlgoList; - - bool myOkHypothesis; - bool myOkAlgorithm; - - SMESH::SMESH_Hypothesis_var myHypothesis; - SMESH::SMESH_Hypothesis_var myAlgorithm; - - SMESH::SMESH_Mesh_var myMesh; + QStringList HypoList; + QStringList AlgoList; - QButtonGroup* GroupConstructors; - QRadioButton* Constructor1; QGroupBox* GroupButtons; QPushButton* buttonOk; QPushButton* buttonCancel; QPushButton* buttonApply; + QGroupBox* GroupC1; QLabel* TextLabel_NameMesh ; QLineEdit* LineEdit_NameMesh ; @@ -119,22 +105,13 @@ private: QLineEdit* LineEditC1A1Algo; private slots: - - void ConstructorsClicked(int constructorId); void ClickOnOk(); + bool ClickOnApply(); void ClickOnCancel(); - void ClickOnApply(); void SetEditCurrentArgument() ; void SelectionIntoArgument() ; void DeactivateActiveDialog() ; void ActivateThisDialog() ; - void TextChangedInLineEdit(const QString& newText) ; - -protected: - QGridLayout* SMESHGUI_InitMeshDlgLayout; - QGridLayout* GroupConstructorsLayout; - QGridLayout* GroupButtonsLayout; - QGridLayout* GroupC1Layout; }; #endif // DIALOGBOX_INIT_MESH_H diff --git a/src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx b/src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx index 473d2ab45..b1946d689 100644 --- a/src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx @@ -32,369 +32,413 @@ using namespace std; #include "SMESHGUI.h" #include "QAD_Application.h" #include "QAD_Desktop.h" +#include "QAD_WaitCursor.h" #include "utilities.h" // QT Includes #include #include +#include +#include #include -#include -#include -#include #include +#include -/* - * Constructs a SMESHGUI_MeshInfosDlg which is a child of 'parent', with the - * name 'name' and widget flags set to 'f' - * - * The dialog will by default be modeless, unless you set 'modal' to - * TRUE to construct a modal dialog. - */ -SMESHGUI_MeshInfosDlg::SMESHGUI_MeshInfosDlg( QWidget* parent, const char* name, SALOME_Selection* Sel, bool modal, WFlags fl ) - : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ) -{ - if ( !name ) - setName( "SMESHGUI_MeshInfosDlg" ); - setCaption( tr( "SMESH_MESHINFO_TITLE" ) ); - setSizeGripEnabled( TRUE ); - - SMESHGUI_MeshInfosDlgLayout = new QVBoxLayout( this ); - SMESHGUI_MeshInfosDlgLayout->setSpacing( 6 ); - SMESHGUI_MeshInfosDlgLayout->setMargin( 11 ); - - /****************************************************************/ - GroupBox1 = new QGroupBox( this, "GroupBox1" ); - GroupBox1->setTitle( tr( "SMESH_MESHINFO_NB1D" ) ); - GroupBox1->setColumnLayout(0, Qt::Vertical ); - GroupBox1->layout()->setSpacing( 0 ); - GroupBox1->layout()->setMargin( 0 ); - QGridLayout* GroupBox1Layout = new QGridLayout( GroupBox1->layout() ); - GroupBox1Layout->setAlignment( Qt::AlignTop ); - GroupBox1Layout->setSpacing( 6 ); - GroupBox1Layout->setMargin( 11 ); - - TextLabel11 = new QLabel( GroupBox1, "TextLabel11" ); - TextLabel11->setMinimumWidth( 100 ); - TextLabel11->setText( tr( "SMESH_MESHINFO_NODES" ) ); - GroupBox1Layout->addWidget( TextLabel11, 0, 0 ); - - TextLabel12 = new QLabel( GroupBox1, "TextLabel12" ); - TextLabel12->setMinimumWidth( 100 ); - TextLabel12->setText( tr( "SMESH_MESHINFO_EDGES" ) ); - GroupBox1Layout->addWidget( TextLabel12, 1, 0 ); - - TextLabel13 = new QLabel( GroupBox1, "TextLabel13" ); - TextLabel13->setMinimumWidth( 100 ); - GroupBox1Layout->addWidget( TextLabel13, 0, 1 ); - - TextLabel14 = new QLabel( GroupBox1, "TextLabel14" ); - TextLabel14->setMinimumWidth( 100 ); - GroupBox1Layout->addWidget( TextLabel14, 1, 1 ); - SMESHGUI_MeshInfosDlgLayout->addWidget( GroupBox1 ); - - /****************************************************************/ - GroupBox2 = new QGroupBox( this, "GroupBox2" ); - GroupBox2->setTitle( tr( "SMESH_MESHINFO_NB2D" ) ); - GroupBox2->setColumnLayout(0, Qt::Vertical ); - GroupBox2->layout()->setSpacing( 0 ); - GroupBox2->layout()->setMargin( 0 ); - QGridLayout* GroupBox2Layout = new QGridLayout( GroupBox2->layout() ); - GroupBox2Layout->setAlignment( Qt::AlignTop ); - GroupBox2Layout->setSpacing( 6 ); - GroupBox2Layout->setMargin( 11 ); - - TextLabel21 = new QLabel( GroupBox2, "TextLabel21" ); - TextLabel21->setMinimumWidth( 100 ); - TextLabel21->setText( tr( "SMESH_MESHINFO_TRIANGLES" ) ); - GroupBox2Layout->addWidget( TextLabel21, 0, 0 ); - - TextLabel22 = new QLabel( GroupBox2, "TextLabel22" ); - TextLabel22->setMinimumWidth( 100 ); - TextLabel22->setText( tr( "SMESH_MESHINFO_QUADRANGLES" ) ); - GroupBox2Layout->addWidget( TextLabel22, 1, 0 ); - - TextLabel23 = new QLabel( GroupBox2, "TextLabel23" ); - TextLabel23->setMinimumWidth( 100 ); - GroupBox2Layout->addWidget( TextLabel23, 0, 1 ); - - TextLabel24 = new QLabel( GroupBox2, "TextLabel24" ); - TextLabel24->setMinimumWidth( 100 ); - GroupBox2Layout->addWidget( TextLabel24, 1, 1 ); - SMESHGUI_MeshInfosDlgLayout->addWidget( GroupBox2 ); - - /****************************************************************/ - GroupBox3 = new QGroupBox( this, "GroupBox3" ); - GroupBox3->setTitle( tr( "SMESH_MESHINFO_NB3D" ) ); - GroupBox3->setColumnLayout(0, Qt::Vertical ); - GroupBox3->layout()->setSpacing( 0 ); - GroupBox3->layout()->setMargin( 0 ); - QGridLayout* GroupBox3Layout = new QGridLayout( GroupBox3->layout() ); - GroupBox3Layout->setAlignment( Qt::AlignTop ); - GroupBox3Layout->setSpacing( 6 ); - GroupBox3Layout->setMargin( 11 ); - - TextLabel31 = new QLabel( GroupBox3, "TextLabel31" ); - TextLabel31->setMinimumWidth( 100 ); - TextLabel31->setText( tr( "SMESH_MESHINFO_TETRAS" ) ); - GroupBox3Layout->addWidget( TextLabel31, 0, 0 ); - - TextLabel32 = new QLabel( GroupBox3, "TextLabel32" ); - TextLabel32->setMinimumWidth( 100 ); - TextLabel32->setText( tr( "SMESH_MESHINFO_HEXAS" ) ); - GroupBox3Layout->addWidget( TextLabel32, 1, 0 ); - - TextLabel33 = new QLabel( GroupBox3, "TextLabel33" ); - TextLabel33->setMinimumWidth( 100 ); - GroupBox3Layout->addWidget( TextLabel33, 0, 1 ); - - TextLabel34 = new QLabel( GroupBox3, "TextLabel34" ); - TextLabel34->setMinimumWidth( 100 ); - GroupBox3Layout->addWidget( TextLabel34, 1, 1 ); - SMESHGUI_MeshInfosDlgLayout->addWidget( GroupBox3 ); - - /****************************************************************/ - QGroupBox* GroupButtons = new QGroupBox( this, "GroupButtons" ); - GroupButtons->setColumnLayout(0, Qt::Vertical ); - GroupButtons->layout()->setSpacing( 0 ); - GroupButtons->layout()->setMargin( 0 ); - QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() ); - GroupButtonsLayout->setAlignment( Qt::AlignTop ); - GroupButtonsLayout->setSpacing( 6 ); - GroupButtonsLayout->setMargin( 11 ); - - GroupButtonsLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 0 ); - buttonOk = new QPushButton( GroupButtons, "buttonOk" ); - buttonOk->setText( tr( "SMESH_BUT_OK" ) ); - buttonOk->setAutoDefault( TRUE ); - buttonOk->setDefault( TRUE ); - GroupButtonsLayout->addWidget( buttonOk, 0, 1 ); - GroupButtonsLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 2 ); - SMESHGUI_MeshInfosDlgLayout->addWidget( GroupButtons ); - /****************************************************************/ - - Init( Sel ) ; -} - -/* - * Destroys the object and frees any allocated resources - */ -SMESHGUI_MeshInfosDlg::~SMESHGUI_MeshInfosDlg() -{ - // no need to delete child widgets, Qt does it all for us -} +#define COLONIZE( str ) ( QString( str ).contains( ":" ) > 0 ? QString( str ) : QString( str ) + " :" ) //================================================================================= -// function : Init() -// purpose : +/*! + * SMESHGUI_MeshInfosDlg::SMESHGUI_MeshInfosDlg + * + * Constructor + */ //================================================================================= -void SMESHGUI_MeshInfosDlg::Init( SALOME_Selection* Sel ) -{ - mySelection = Sel ; - - mySMESHGUI = SMESHGUI::GetSMESHGUI() ; - myStudy = mySMESHGUI->GetActiveStudy()->getStudyDocument(); - - Engines::Component_var comp = QAD_Application::getDesktop()->getEngine("FactoryServer", "SMESH"); - myCompMesh = SMESH::SMESH_Gen::_narrow(comp); - - int nbSel = mySelection->IObjectCount(); - - TextLabel13->setText( "0" ); - TextLabel14->setText( "0" ); - TextLabel23->setText( "0" ); - TextLabel24->setText( "0" ); - TextLabel33->setText( "0" ); - TextLabel34->setText( "0" ); - - //gets the selected mesh - if ( nbSel == 1 ) { - Handle(SALOME_InteractiveObject) IObject = mySelection->firstIObject(); - Standard_Boolean res; - myMesh = mySMESHGUI->ConvertIOinMesh( IObject, res ); - if ( res ) - DumpMeshInfos(); - } - - mySMESHGUI->SetActiveDialogBox( (QDialog*)this ) ; - - /* signals and slots connections */ - connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) ); - connect( mySMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ; - connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) ); - /* to close dialog if study change */ - connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( ClickOnOk() ) ) ; - - /* Move widget on the botton right corner of main widget */ - int x, y ; - mySMESHGUI->DefineDlgPosition( this, x, y ) ; - this->move( x, y ) ; - this->show() ; /* Displays Dialog */ - - return ; +SMESHGUI_MeshInfosDlg::SMESHGUI_MeshInfosDlg( QWidget* parent, const char* name, bool modal, WFlags fl ) + : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose ) +{ + if ( !name ) + setName( "SMESHGUI_MeshInfosDlg" ); + setCaption( tr( "SMESH_MESHINFO_TITLE" ) ); + setSizeGripEnabled( TRUE ); + + myStartSelection = true; + myIsActiveWindow = true; + + QVBoxLayout* aTopLayout = new QVBoxLayout( this ); + aTopLayout->setSpacing( 6 ); aTopLayout->setMargin( 11 ); + + // select button & label + QPixmap image0( QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr( "ICON_SELECT" ) ) ); + mySelectBtn = new QPushButton( this, "mySelectBtn" ); + mySelectBtn->setPixmap( image0 ); + mySelectBtn->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); + + mySelectLab = new QLabel( this, "mySelectLab" ); + mySelectLab->setAlignment( AlignCenter ); + QFont fnt = mySelectLab->font(); fnt.setBold( true ); + mySelectLab->setFont( fnt ); + + QHBoxLayout* aSelectLayout = new QHBoxLayout; + aSelectLayout->setMargin( 0 ); aSelectLayout->setSpacing( 0 ); + aSelectLayout->addWidget( mySelectBtn ); + aSelectLayout->addWidget( mySelectLab ); + + // top widget stack + myWGStack = new QWidgetStack( this ); + + // no valid selection + QWidget* myBadWidget = new QWidget( myWGStack ); + QVBoxLayout* aBadLayout = new QVBoxLayout( myBadWidget ); + QLabel* myBadLab = new QLabel( tr( "SMESH_BAD_SELECTION" ), myBadWidget, "myBadLab" ); + myBadLab->setAlignment( Qt::AlignCenter ); + myBadLab->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) ); + aBadLayout->addWidget( myBadLab ); + myWGStack->addWidget( myBadWidget, 0 ); + + // mesh + myMeshWidget = new QWidget( myWGStack ); + QGridLayout* aMeshLayout = new QGridLayout( myMeshWidget ); + aMeshLayout->setSpacing( 6 ); aMeshLayout->setMargin( 0 ); + myWGStack->addWidget( myMeshWidget ); + + // --> name + QLabel* myMeshNameLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_NAME" ) ), myMeshWidget, "myMeshNameLab" ); + myMeshName = new QLabel( myMeshWidget, "myMeshName" ); + myMeshName->setMinimumWidth( 100 ); + QFrame* line1 = new QFrame( myMeshWidget ); + line1->setFrameStyle( QFrame::HLine | QFrame::Sunken ); + + // --> nodes + QLabel* myMeshNbNodesLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_NODES" ) ), myMeshWidget, "myMeshNbNodesLab" ); + myMeshNbNodes = new QLabel( myMeshWidget, "myMeshNbNodes" ); + myMeshNbNodes->setMinimumWidth( 100 ); + + // --> edges + QLabel* myMeshNbEdgesLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_EDGES" ) ), myMeshWidget, "myMeshNbEdgesLab" ); + myMeshNbEdges = new QLabel( myMeshWidget, "myMeshNbEdges" ); + myMeshNbEdges->setMinimumWidth( 100 ); + + // --> faces + myMeshFacesGroup = new QGroupBox( tr( "SMESH_MESHINFO_FACES" ), myMeshWidget, "myMeshFacesGroup" ); + myMeshFacesGroup->setColumnLayout(0, Qt::Vertical ); + myMeshFacesGroup->layout()->setSpacing( 0 ); myMeshFacesGroup->layout()->setMargin( 0 ); + QGridLayout* myMeshFacesGroupLayout = new QGridLayout( myMeshFacesGroup->layout() ); + myMeshFacesGroupLayout->setAlignment( Qt::AlignTop ); + myMeshFacesGroupLayout->setSpacing( 6 ); myMeshFacesGroupLayout->setMargin( 11 ); + + // --> faces --> total + QLabel* myMeshNbFacesLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_TOTAL" ) ), myMeshFacesGroup, "myMeshNbFacesLab" ); + myMeshNbFacesLab->setFont( fnt ); + myMeshNbFaces = new QLabel( myMeshFacesGroup, "myMeshNbFaces" ); + myMeshNbFaces->setMinimumWidth( 100 ); + myMeshNbFaces->setFont( fnt ); + + // --> faces --> triangles + QLabel* myMeshNbTrianglesLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_TRIANGLES" ) ), myMeshFacesGroup, "myMeshNbTrianglesLab" ); + myMeshNbTriangles = new QLabel( myMeshFacesGroup, "myMeshNbTriangles" ); + myMeshNbTriangles->setMinimumWidth( 100 ); + + // --> faces --> quadrangles + QLabel* myMeshNbQuadranglesLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_QUADRANGLES" ) ), myMeshFacesGroup, "myMeshNbQuadranglesLab" ); + myMeshNbQuadrangles = new QLabel( myMeshFacesGroup, "myMeshNbQuadrangles" ); + myMeshNbQuadrangles->setMinimumWidth( 100 ); + + myMeshFacesGroupLayout->addWidget( myMeshNbFacesLab, 0, 0 ); + myMeshFacesGroupLayout->addWidget( myMeshNbFaces, 0, 1 ); + myMeshFacesGroupLayout->addWidget( myMeshNbTrianglesLab, 1, 0 ); + myMeshFacesGroupLayout->addWidget( myMeshNbTriangles, 1, 1 ); + myMeshFacesGroupLayout->addWidget( myMeshNbQuadranglesLab, 2, 0 ); + myMeshFacesGroupLayout->addWidget( myMeshNbQuadrangles, 2, 1 ); + + // --> volumes + myMeshVolumesGroup = new QGroupBox( tr( "SMESH_MESHINFO_VOLUMES" ), myMeshWidget, "myMeshVolumesGroup" ); + myMeshVolumesGroup->setColumnLayout(0, Qt::Vertical ); + myMeshVolumesGroup->layout()->setSpacing( 0 ); myMeshVolumesGroup->layout()->setMargin( 0 ); + QGridLayout* myMeshVolumesGroupLayout = new QGridLayout( myMeshVolumesGroup->layout() ); + myMeshVolumesGroupLayout->setAlignment( Qt::AlignTop ); + myMeshVolumesGroupLayout->setSpacing( 6 ); myMeshVolumesGroupLayout->setMargin( 11 ); + + // --> volumes --> total + QLabel* myMeshNbVolumesLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_TOTAL" ) ), myMeshVolumesGroup, "myMeshNbVolumesLab" ); + myMeshNbVolumesLab->setFont( fnt ); + myMeshNbVolumes = new QLabel( myMeshVolumesGroup, "myMeshNbVolumes" ); + myMeshNbVolumes->setMinimumWidth( 100 ); + myMeshNbVolumes->setFont( fnt ); + + // --> volumes --> tetrahedrons + QLabel* myMeshNbTetraLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_TETRAS" ) ), myMeshVolumesGroup, "myMeshNbTetraLab" ); + myMeshNbTetra = new QLabel( myMeshVolumesGroup, "myMeshNbTetra" ); + myMeshNbTetra->setMinimumWidth( 100 ); + + // --> volumes --> hexahedrons + QLabel* myMeshNbHexaLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_HEXAS" ) ), myMeshVolumesGroup, "myMeshNbHexaLab" ); + myMeshNbHexa = new QLabel( myMeshVolumesGroup, "myMeshNbHexa" ); + myMeshNbHexaLab->setMinimumWidth( 100 ); + + // --> volumes --> prisms + QLabel* myMeshNbPrismLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_PRISMS" ) ), myMeshVolumesGroup, "myMeshNbPrismLab" ); + myMeshNbPrism = new QLabel( myMeshVolumesGroup, "myMeshNbPrism" ); + myMeshNbPrism->setMinimumWidth( 100 ); + + // --> volumes --> pyramids + QLabel* myMeshNbPyraLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_PYRAS" ) ), myMeshVolumesGroup, "myMeshNbPyraLab" ); + myMeshNbPyra = new QLabel( myMeshVolumesGroup, "myMeshNbPyra" ); + myMeshNbPyra->setMinimumWidth( 100 ); + + myMeshVolumesGroupLayout->addWidget( myMeshNbVolumesLab, 0, 0 ); + myMeshVolumesGroupLayout->addWidget( myMeshNbVolumes, 0, 1 ); + myMeshVolumesGroupLayout->addWidget( myMeshNbTetraLab, 1, 0 ); + myMeshVolumesGroupLayout->addWidget( myMeshNbTetra, 1, 1 ); + myMeshVolumesGroupLayout->addWidget( myMeshNbHexaLab, 2, 0 ); + myMeshVolumesGroupLayout->addWidget( myMeshNbHexa, 2, 1 ); + myMeshVolumesGroupLayout->addWidget( myMeshNbPrismLab, 3, 0 ); + myMeshVolumesGroupLayout->addWidget( myMeshNbPrism, 3, 1 ); + myMeshVolumesGroupLayout->addWidget( myMeshNbPyraLab, 4, 0 ); + myMeshVolumesGroupLayout->addWidget( myMeshNbPyra, 4, 1 ); + + aMeshLayout->addWidget( myMeshNameLab, 0, 0 ); + aMeshLayout->addWidget( myMeshName, 0, 1 ); + aMeshLayout->addMultiCellWidget( line1, 1, 1, 0, 1 ); + aMeshLayout->addWidget( myMeshNbNodesLab, 2, 0 ); + aMeshLayout->addWidget( myMeshNbNodes, 2, 1 ); + aMeshLayout->addWidget( myMeshNbEdgesLab, 3, 0 ); + aMeshLayout->addWidget( myMeshNbEdges, 3, 1 ); + aMeshLayout->addMultiCellWidget( myMeshFacesGroup, 4, 4, 0, 1 ); + aMeshLayout->addMultiCellWidget( myMeshVolumesGroup, 5, 5, 0, 1 ); + aMeshLayout->addItem( new QSpacerItem( 5, 5, QSizePolicy::Minimum, QSizePolicy::Expanding ), 6, 0 ); + + // submesh + mySubMeshWidget = new QWidget( myWGStack ); + QGridLayout* aSubMeshLayout = new QGridLayout( mySubMeshWidget ); + aSubMeshLayout->setSpacing( 6 ); aSubMeshLayout->setMargin( 0 ); + myWGStack->addWidget( mySubMeshWidget ); + + // --> name + QLabel* mySubMeshNameLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_NAME" ) ), mySubMeshWidget, "mySubMeshNameLab" ); + mySubMeshName = new QLabel( mySubMeshWidget, "mySubMeshName" ); + mySubMeshName->setMinimumWidth( 100 ); + QFrame* line2 = new QFrame( mySubMeshWidget ); + line2->setFrameStyle( QFrame::HLine | QFrame::Sunken ); + + // --> nodes + QLabel* mySubMeshNbNodesLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_NODES" ) ), mySubMeshWidget, "mySubMeshNbNodesLab" ); + mySubMeshNbNodes = new QLabel( mySubMeshWidget, "mySubMeshNbNodes" ); + mySubMeshNbNodes->setMinimumWidth( 100 ); + + // --> elements + mySubMeshElementsGroup = new QGroupBox( tr( "SMESH_MESHINFO_ELEMENTS" ), mySubMeshWidget, "mySubMeshElementsGroup" ); + mySubMeshElementsGroup->setColumnLayout(0, Qt::Vertical ); + mySubMeshElementsGroup->layout()->setSpacing( 0 ); mySubMeshElementsGroup->layout()->setMargin( 0 ); + QGridLayout* mySubMeshElementsGroupLayout = new QGridLayout( mySubMeshElementsGroup->layout() ); + mySubMeshElementsGroupLayout->setAlignment( Qt::AlignTop ); + mySubMeshElementsGroupLayout->setSpacing( 6 ); mySubMeshElementsGroupLayout->setMargin( 11 ); + + // --> elements --> total + QLabel* mySubMeshNbElementsLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_TOTAL" ) ), mySubMeshElementsGroup, "mySubMeshNbElementsLab" ); + mySubMeshNbElementsLab->setFont( fnt ); + mySubMeshNbElements = new QLabel( mySubMeshElementsGroup, "mySubMeshNbElements" ); + mySubMeshNbElements->setMinimumWidth( 100 ); + mySubMeshNbElements->setFont( fnt ); + + // --> elements --> edges + QLabel* mySubMeshNbEdgesLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_EDGES" ) ), mySubMeshElementsGroup, "mySubMeshNbEdgesLab" ); + mySubMeshNbEdges = new QLabel( mySubMeshElementsGroup, "mySubMeshNbEdges" ); + mySubMeshNbEdges->setMinimumWidth( 100 ); + + // --> elements --> faces + QLabel* mySubMeshNbFacesLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_FACES" ) ), mySubMeshElementsGroup, "mySubMeshNbFacesLab" ); + mySubMeshNbFaces = new QLabel( mySubMeshElementsGroup, "mySubMeshNbFaces" ); + mySubMeshNbFaces->setMinimumWidth( 100 ); + + // --> elements --> volumes + QLabel* mySubMeshNbVolumesLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_VOLUMES" ) ), mySubMeshElementsGroup, "mySubMeshNbVolumesLab" ); + mySubMeshNbVolumes = new QLabel( mySubMeshElementsGroup, "mySubMeshNbVolumes" ); + mySubMeshNbVolumes->setMinimumWidth( 100 ); + + mySubMeshElementsGroupLayout->addWidget( mySubMeshNbElementsLab, 0, 0 ); + mySubMeshElementsGroupLayout->addWidget( mySubMeshNbElements, 0, 1 ); + mySubMeshElementsGroupLayout->addWidget( mySubMeshNbEdgesLab, 1, 0 ); + mySubMeshElementsGroupLayout->addWidget( mySubMeshNbEdges, 1, 1 ); + mySubMeshElementsGroupLayout->addWidget( mySubMeshNbFacesLab, 2, 0 ); + mySubMeshElementsGroupLayout->addWidget( mySubMeshNbFaces, 2, 1 ); + mySubMeshElementsGroupLayout->addWidget( mySubMeshNbVolumesLab, 3, 0 ); + mySubMeshElementsGroupLayout->addWidget( mySubMeshNbVolumes, 3, 1 ); + + aSubMeshLayout->addWidget( mySubMeshNameLab, 0, 0 ); + aSubMeshLayout->addWidget( mySubMeshName, 0, 1 ); + aSubMeshLayout->addMultiCellWidget( line2, 1, 1, 0, 1 ); + aSubMeshLayout->addWidget( mySubMeshNbNodesLab, 2, 0 ); + aSubMeshLayout->addWidget( mySubMeshNbNodes, 2, 1 ); + aSubMeshLayout->addMultiCellWidget( mySubMeshElementsGroup, 3, 3, 0, 1 ); + aSubMeshLayout->addItem( new QSpacerItem( 5, 5, QSizePolicy::Minimum, QSizePolicy::Expanding ), 4, 0 ); + + // group + myGroupWidget = new QWidget( myWGStack ); + QGridLayout* myGroupWidgetLayout = new QGridLayout( myGroupWidget ); + myGroupWidgetLayout->setSpacing( 6 ); myGroupWidgetLayout->setMargin( 0 ); + myWGStack->addWidget( myGroupWidget ); + + // --> name + QLabel* myGroupNameLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_NAME" ) ), myGroupWidget, "myGroupNameLab" ); + myGroupName = new QLabel( myGroupWidget, "myGroupName" ); + myGroupName->setMinimumWidth( 100 ); + QFrame* line3 = new QFrame( myGroupWidget ); + line3->setFrameStyle( QFrame::HLine | QFrame::Sunken ); + + // --> type + QLabel* myGroupTypeLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_TYPE" ) ), myGroupWidget, "myGroupTypeLab" ); + myGroupType = new QLabel( myGroupWidget, "myGroupType" ); + myGroupType->setMinimumWidth( 100 ); + + // --> number of entities + QLabel* myGroupNbLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_ENTITIES" ) ), myGroupWidget, "myGroupNbLab" ); + myGroupNb = new QLabel( myGroupWidget, "myGroupNb" ); + myGroupNb->setMinimumWidth( 100 ); + + myGroupWidgetLayout->addWidget( myGroupNameLab, 0, 0 ); + myGroupWidgetLayout->addWidget( myGroupName, 0, 1 ); + myGroupWidgetLayout->addMultiCellWidget( line3, 1, 1, 0, 1 ); + myGroupWidgetLayout->addWidget( myGroupTypeLab, 2, 0 ); + myGroupWidgetLayout->addWidget( myGroupType, 2, 1 ); + myGroupWidgetLayout->addWidget( myGroupNbLab, 3, 0 ); + myGroupWidgetLayout->addWidget( myGroupNb, 3, 1 ); + myGroupWidgetLayout->addItem( new QSpacerItem( 5, 5, QSizePolicy::Minimum, QSizePolicy::Expanding ), 4, 0 ); + + // buttons + myButtonsGroup = new QGroupBox( this, "myButtonsGroup" ); + myButtonsGroup->setColumnLayout(0, Qt::Vertical ); + myButtonsGroup->layout()->setSpacing( 0 ); myButtonsGroup->layout()->setMargin( 0 ); + QHBoxLayout* myButtonsGroupLayout = new QHBoxLayout( myButtonsGroup->layout() ); + myButtonsGroupLayout->setAlignment( Qt::AlignTop ); + myButtonsGroupLayout->setSpacing( 6 ); myButtonsGroupLayout->setMargin( 11 ); + + // buttons --> OK button + myOkBtn = new QPushButton( tr( "SMESH_BUT_OK" ), myButtonsGroup, "myOkBtn" ); + myOkBtn->setAutoDefault( TRUE ); myOkBtn->setDefault( TRUE ); + myButtonsGroupLayout->addStretch(); + myButtonsGroupLayout->addWidget( myOkBtn ); + myButtonsGroupLayout->addStretch(); + + aTopLayout->addLayout( aSelectLayout ); + aTopLayout->addWidget( myWGStack ); + aTopLayout->addWidget( myButtonsGroup ); + + mySelection = SALOME_Selection::Selection( SMESHGUI::GetSMESHGUI()->GetActiveStudy()->getSelection() ); + SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this ) ; + + // connect signals + connect( myOkBtn, SIGNAL( clicked() ), this, SLOT( close() ) ); + connect( mySelectBtn, SIGNAL( clicked() ), this, SLOT( onStartSelection() ) ); + connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( close() ) ) ; + connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ; + connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( onSelectionChanged() ) ); + + // resize and move dialog, then show + int x, y; + SMESHGUI::GetSMESHGUI()->DefineDlgPosition( this, x, y ); + this->move( x, y ); + this->show(); + + // init dialog with current selection + onSelectionChanged(); } //================================================================================= -// function : genEdgeKey -// purpose : edge counting helper; -// packs two long integers into one 8-byte value (treated as double by the caller); -// the order of arguments is insignificant +/*! + * SMESHGUI_MeshInfosDlg::~SMESHGUI_MeshInfosDlg + * + * Destructor + */ //================================================================================= -void genEdgeKey(long a, long b, void* key) +SMESHGUI_MeshInfosDlg::~SMESHGUI_MeshInfosDlg() { - long* lKey = (long*)key; - *lKey = (a < b) ? a : b; - *(++lKey) = (a < b) ? b : a; } //================================================================================= -// function : DumpMeshInfos() -// purpose : +/*! + * SMESHGUI_MeshInfosDlg::DumpMeshInfos + */ //================================================================================= void SMESHGUI_MeshInfosDlg::DumpMeshInfos() { - int nbOfNodes = myMesh->NbNodes(); - int nbOfEdges = myMesh->NbEdges(); - int nbOfTriangles = myMesh->NbTriangles(); - int nbOfQuadrangles = myMesh->NbQuadrangles(); - int nbOfTetras = myMesh->NbTetras(); - int nbOfHexas = myMesh->NbHexas(); - - /* - int nbOfNodes = 0 ; - int nbOfEdges = 0 ; - int nbOfTriangles = 0 ; - int nbOfQuadrangles = 0 ; - int nbOfTetras = 0 ; - int nbOfHexas = 0 ; - int nbCells = 0 ; - int CellType = 0 ; - QMap aMapOfEdges; - - Standard_Boolean result; - SMESH_Actor* MeshActor = mySMESHGUI->FindActor(myMesh, result, true); - - if ( result ) { - vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( MeshActor->DataSource ); - vtkPoints *Pts = ugrid->GetPoints(); - nbOfNodes = Pts->GetNumberOfPoints(); - int nbCells = ugrid->GetNumberOfCells(); - - for ( int i = 0; i < nbCells; i++ ) { - vtkCell* cellPtr = ugrid->GetCell(i); - CellType = cellPtr->GetCellType(); - switch (CellType) - { - case 3: //Edges - { - nbOfEdges++; - break; - } - case 5: //Triangles - { - nbOfTriangles++; - - for (int edgeNum = 0; edgeNum < 3; edgeNum++) { - vtkCell* edgePtr = cellPtr->GetEdge(edgeNum); - double anEdgeKey; - genEdgeKey(edgePtr->GetPointId(0), edgePtr->GetPointId(1), &anEdgeKey); - if (!aMapOfEdges.contains(anEdgeKey)) { - nbOfEdges++; - aMapOfEdges.insert(anEdgeKey, 0); - } - } - break; - } - case 9: //Quadrangles - { - nbOfQuadrangles++; - - for (int edgeNum = 0; edgeNum < 4; edgeNum++) { - vtkCell* edgePtr = cellPtr->GetEdge(edgeNum); - double anEdgeKey; - genEdgeKey(edgePtr->GetPointId(0), edgePtr->GetPointId(1), &anEdgeKey); - if (!aMapOfEdges.contains(anEdgeKey)) { - nbOfEdges++; - aMapOfEdges.insert(anEdgeKey, 0); - } - } - break; - } - case 10: //Tetraedras - { - nbOfTetras++; - - for (int edgeNum = 0; edgeNum < 6; edgeNum++) { - vtkCell* edgePtr = cellPtr->GetEdge(edgeNum); - double anEdgeKey; - genEdgeKey(edgePtr->GetPointId(0), edgePtr->GetPointId(1), &anEdgeKey); - if (!aMapOfEdges.contains(anEdgeKey)) { - nbOfEdges++; - aMapOfEdges.insert(anEdgeKey, 0); - } - } - break; - } - case 12: //Hexahedras - { - nbOfHexas++; - - for (int edgeNum = 0; edgeNum < 12; edgeNum++) { - vtkCell* edgePtr = cellPtr->GetEdge(edgeNum); - double anEdgeKey; - genEdgeKey(edgePtr->GetPointId(0), edgePtr->GetPointId(1), &anEdgeKey); - if (!aMapOfEdges.contains(anEdgeKey)) { - nbOfEdges++; - aMapOfEdges.insert(anEdgeKey, 0); - } - } - break; + QAD_WaitCursor wc; + int nbSel = mySelection->IObjectCount(); + if ( nbSel == 1 ) { + myStartSelection = false; + mySelectLab->setText( "" ); + Handle(SALOME_InteractiveObject) IObject = mySelection->firstIObject(); + SALOMEDS::SObject_var aSO = SMESHGUI::GetSMESHGUI()->GetStudy()->FindObjectID( IObject->getEntry() ); + if ( !aSO->_is_nil() ) { + CORBA::Object_var anObject = aSO->GetObject(); + if ( !CORBA::is_nil( anObject ) ) { + SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( anObject ); + if ( !aMesh->_is_nil() ) { + myWGStack->raiseWidget( myMeshWidget ); + setCaption( tr( "SMESH_MESHINFO_TITLE" ) + " [" + tr("SMESH_OBJECT_MESH") +"]" ); + myMeshName->setText( aSO->GetName() ); + myMeshNbNodes->setNum( (int)aMesh->NbNodes() ); + myMeshNbEdges->setNum( (int)aMesh->NbEdges() ); + myMeshNbFaces->setNum( (int)aMesh->NbFaces() ); + myMeshNbTriangles->setNum( (int)aMesh->NbTriangles() ); + myMeshNbQuadrangles->setNum( (int)aMesh->NbQuadrangles() ); + myMeshNbVolumes->setNum( (int)aMesh->NbVolumes() ); + myMeshNbTetra->setNum( (int)aMesh->NbTetras() ); + myMeshNbHexa->setNum( (int)aMesh->NbHexas() ); + myMeshNbPrism->setNum( (int)aMesh->NbPrisms() ); + myMeshNbPyra->setNum( (int)aMesh->NbPyramids() ); + return; + } + SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( anObject ); + if ( !aSubMesh->_is_nil() ) { + myWGStack->raiseWidget( mySubMeshWidget ); + setCaption( tr( "SMESH_MESHINFO_TITLE" ) + " [" + tr("SMESH_SUBMESH") +"]" ); + mySubMeshName->setText( aSO->GetName() ); + mySubMeshNbNodes->setNum( (int)aSubMesh->GetNumberOfNodes() ); + mySubMeshNbElements->setNum( (int)aSubMesh->GetNumberOfElements() ); + mySubMeshNbEdges->setNum( (int)( aSubMesh->GetElementsByType( SMESH::EDGE )->length() ) ); + mySubMeshNbFaces->setNum( (int)( aSubMesh->GetElementsByType( SMESH::FACE )->length() ) ); + mySubMeshNbVolumes->setNum( (int)( aSubMesh->GetElementsByType( SMESH::VOLUME )->length() ) ); + return; + } + SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow( anObject ); + if ( !aGroup->_is_nil() ) { + myWGStack->raiseWidget( myGroupWidget ); + setCaption( tr( "SMESH_MESHINFO_TITLE" ) + " [" + tr("SMESH_GROUP") +"]" ); + myGroupName->setText( aSO->GetName() ); + int aType = aGroup->GetType(); + QString strType; + switch ( aType ) { + case SMESH::NODE: + strType = "SMESH_MESHINFO_NODES"; break; + case SMESH::EDGE: + strType = "SMESH_MESHINFO_EDGES"; break; + case SMESH::FACE: + strType = "SMESH_MESHINFO_FACES"; break; + case SMESH::VOLUME: + strType = "SMESH_MESHINFO_VOLUMES"; break; + default: + strType = "SMESH_MESHINFO_ALL_TYPES"; break; } + + myGroupType->setText( tr( strType ) ); + myGroupNb->setNum( (int)aGroup->Size() ); + return; } + } } } - */ - TextLabel13->setText( tr( "%1" ).arg(nbOfNodes) ); - TextLabel14->setText( tr( "%1" ).arg(nbOfEdges) ); - TextLabel23->setText( tr( "%1" ).arg(nbOfTriangles) ); - TextLabel24->setText( tr( "%1" ).arg(nbOfQuadrangles) ); - TextLabel33->setText( tr( "%1" ).arg(nbOfTetras) ); - TextLabel34->setText( tr( "%1" ).arg(nbOfHexas) ); -} - -//================================================================================= -// function : ClickOnOk() -// purpose : -//================================================================================= -void SMESHGUI_MeshInfosDlg::ClickOnOk() -{ - disconnect( mySelection, 0, this, 0 ); - mySMESHGUI->ResetState() ; - reject() ; - return ; + myWGStack->raiseWidget( 0 ); + setCaption( tr( "SMESH_MESHINFO_TITLE" ) ); } //================================================================================= // function : SelectionIntoArgument() // purpose : Called when selection has changed //================================================================================= -void SMESHGUI_MeshInfosDlg::SelectionIntoArgument() +void SMESHGUI_MeshInfosDlg::onSelectionChanged() { - TextLabel13->setText( "0" ); - TextLabel14->setText( "0" ); - TextLabel23->setText( "0" ); - TextLabel24->setText( "0" ); - TextLabel33->setText( "0" ); - TextLabel34->setText( "0" ); - - int nbSel = mySelection->IObjectCount(); - if ( nbSel == 1 ) { - Handle(SALOME_InteractiveObject) IObject = mySelection->firstIObject(); - Standard_Boolean res; - myMesh = mySMESHGUI->ConvertIOinMesh( IObject, res ); - if ( res ) - DumpMeshInfos(); - } - return ; + if ( myStartSelection ) + DumpMeshInfos(); } @@ -404,20 +448,21 @@ void SMESHGUI_MeshInfosDlg::SelectionIntoArgument() //================================================================================= void SMESHGUI_MeshInfosDlg::closeEvent( QCloseEvent* e ) { - disconnect( mySelection, 0, this, 0 ); - mySMESHGUI->ResetState() ; - reject() ; - return ; + SMESHGUI::GetSMESHGUI()->ResetState(); + QDialog::closeEvent( e ); } //================================================================================= -// function : enterEvent() -// purpose : when mouse enter onto the QWidget +// function : windowActivationChange() +// purpose : called when window is activated/deactivated //================================================================================= -void SMESHGUI_MeshInfosDlg::enterEvent( QEvent * ) +void SMESHGUI_MeshInfosDlg::windowActivationChange( bool oldActive ) { - ActivateThisDialog() ; + QDialog::windowActivationChange( oldActive ); + if ( isActiveWindow() && myIsActiveWindow != isActiveWindow() ) + ActivateThisDialog() ; + myIsActiveWindow = isActiveWindow(); } @@ -428,8 +473,6 @@ void SMESHGUI_MeshInfosDlg::enterEvent( QEvent * ) void SMESHGUI_MeshInfosDlg::DeactivateActiveDialog() { disconnect( mySelection, 0, this, 0 ); - - return ; } @@ -440,8 +483,18 @@ void SMESHGUI_MeshInfosDlg::DeactivateActiveDialog() void SMESHGUI_MeshInfosDlg::ActivateThisDialog() { /* Emit a signal to deactivate any active dialog */ - mySMESHGUI->EmitSignalDeactivateDialog() ; - - return ; + SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog() ; + connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( onSelectionChanged() ) ); } +//================================================================================= +// function : onStartSelection() +// purpose : starts selection +//================================================================================= +void SMESHGUI_MeshInfosDlg::onStartSelection() +{ + myStartSelection = true; + onSelectionChanged(); + myStartSelection = true; + mySelectLab->setText( tr( "INF_SELECT_OBJECT" ) ); +} diff --git a/src/SMESHGUI/SMESHGUI_MeshInfosDlg.h b/src/SMESHGUI/SMESHGUI_MeshInfosDlg.h index bef45b9b2..c5f65073d 100644 --- a/src/SMESHGUI/SMESHGUI_MeshInfosDlg.h +++ b/src/SMESHGUI/SMESHGUI_MeshInfosDlg.h @@ -29,74 +29,80 @@ #ifndef SMESHGUI_MESHINFOSDLG_H #define SMESHGUI_MESHINFOSDLG_H -#include "SALOME_Selection.h" -#include "QAD_Study.h" - // IDL Headers #include #include CORBA_SERVER_HEADER(SMESH_Gen) #include CORBA_SERVER_HEADER(SMESH_Mesh) // QT Includes -#include #include -class QVBoxLayout; -class QHBoxLayout; -class QGridLayout; + class QGroupBox; class QLabel; class QPushButton; -class SMESHGUI; +class SALOME_Selection; +class QWidgetStack; class SMESHGUI_MeshInfosDlg : public QDialog { Q_OBJECT public: - SMESHGUI_MeshInfosDlg( QWidget* parent = 0, const char* name = 0, SALOME_Selection* Sel = 0, bool modal = FALSE, WFlags fl = 0 ); + SMESHGUI_MeshInfosDlg( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); ~SMESHGUI_MeshInfosDlg(); -private: - - void Init( SALOME_Selection* Sel ) ; - void closeEvent( QCloseEvent* e ) ; - void enterEvent ( QEvent * ) ; /* mouse enter the QWidget */ +protected: + void closeEvent( QCloseEvent* e ); + void windowActivationChange( bool oldActive ); void DumpMeshInfos(); - SMESH::SMESH_Gen_var myCompMesh ; - SMESHGUI* mySMESHGUI ; - SMESH::SMESH_Mesh_var myMesh ; - SALOME_Selection* mySelection ; - SALOMEDS::Study_var myStudy; +private slots: + void onSelectionChanged(); + void DeactivateActiveDialog() ; + void ActivateThisDialog(); + void onStartSelection(); - QGroupBox* GroupBox1; - QLabel* TextLabel12; - QLabel* TextLabel11; - QLabel* TextLabel13; - QLabel* TextLabel14; - QGroupBox* GroupBox2; - QLabel* TextLabel21; - QLabel* TextLabel22; - QLabel* TextLabel23; - QLabel* TextLabel24; - QGroupBox* GroupBox3; - QLabel* TextLabel31; - QLabel* TextLabel32; - QLabel* TextLabel33; - QLabel* TextLabel34; - QPushButton* buttonOk; +private: + SALOME_Selection* mySelection; + bool myStartSelection; + bool myIsActiveWindow; + + QPushButton* mySelectBtn; + QLabel* mySelectLab; -private slots: + QWidgetStack* myWGStack; - void ClickOnOk(); - void SelectionIntoArgument() ; - void DeactivateActiveDialog() ; - void ActivateThisDialog() ; + QWidget* myMeshWidget; + QLabel* myMeshName; + QLabel* myMeshNbNodes; + QLabel* myMeshNbEdges; + QGroupBox* myMeshFacesGroup; + QLabel* myMeshNbFaces; + QLabel* myMeshNbTriangles; + QLabel* myMeshNbQuadrangles; + QGroupBox* myMeshVolumesGroup; + QLabel* myMeshNbVolumes; + QLabel* myMeshNbTetra; + QLabel* myMeshNbHexa; + QLabel* myMeshNbPyra; + QLabel* myMeshNbPrism; + + QWidget* mySubMeshWidget; + QLabel* mySubMeshName; + QLabel* mySubMeshNbNodes; + QGroupBox* mySubMeshElementsGroup; + QLabel* mySubMeshNbElements; + QLabel* mySubMeshNbEdges; + QLabel* mySubMeshNbFaces; + QLabel* mySubMeshNbVolumes; -protected: - QVBoxLayout* SMESHGUI_MeshInfosDlgLayout; - QHBoxLayout* Layout1; + QWidget* myGroupWidget; + QLabel* myGroupName; + QLabel* myGroupType; + QLabel* myGroupNb; + QGroupBox* myButtonsGroup; + QPushButton* myOkBtn; }; #endif // SMESHGUI_MESHINFOSDLG_H diff --git a/src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx b/src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx index 72c2f95e7..f44ffac11 100644 --- a/src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx @@ -26,10 +26,10 @@ // Module : SMESH // $Header$ -using namespace std; #include "SMESHGUI_MoveNodesDlg.h" -#include "SMESHGUI.h" #include "SMESHGUI_SpinBox.h" +#include "SMESH_Actor.h" +#include "SMESHGUI.h" #include "QAD_Application.h" #include "QAD_Desktop.h" @@ -53,8 +53,7 @@ using namespace std; // Open CASCADE Include #include -// VTK Include -#include +using namespace std; //================================================================================= // class : SMESHGUI_MoveNodesDlg() @@ -309,7 +308,7 @@ void SMESHGUI_MoveNodesDlg::ClickOnOk() //================================================================================= void SMESHGUI_MoveNodesDlg::ClickOnCancel() { - QAD_Application::getDesktop()->SetSelectionMode( 4 ); + QAD_Application::getDesktop()->SetSelectionMode( ActorSelection ); disconnect( mySelection, 0, this, 0 ); mySMESHGUI->ResetState() ; mySMESHGUI->EraseSimulationActors(); @@ -347,9 +346,9 @@ void SMESHGUI_MoveNodesDlg::SelectionIntoArgument() return ; } - if ( mySelection->SelectionMode() != 1 ){ + if ( mySelection->SelectionMode() != NodeSelection ){ QAD_MessageBox::warn1 ( QAD_Application::getDesktop(), tr ("SMESH_WRN_WARNING"), - tr ("SMESH_WRN_SELECTIONMODE_NODES"), tr ("SMESH_BUT_YES") ); + tr ("SMESH_WRN_SELECTIONMODE_NODES"), tr ("SMESH_BUT_OK") ); return; } diff --git a/src/SMESHGUI/SMESHGUI_NodesDlg.cxx b/src/SMESHGUI/SMESHGUI_NodesDlg.cxx index 8a757402e..5ae62afc1 100644 --- a/src/SMESHGUI/SMESHGUI_NodesDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_NodesDlg.cxx @@ -284,7 +284,7 @@ void SMESHGUI_NodesDlg::ClickOnApply() //======================================================================= void SMESHGUI_NodesDlg::ClickOnCancel() { - QAD_Application::getDesktop()->SetSelectionMode( 4 ); + QAD_Application::getDesktop()->SetSelectionMode( ActorSelection ); disconnect( mySelection, 0, this, 0 ); myMeshGUI->ResetState() ; myMeshGUI->EraseSimulationActors() ; @@ -316,12 +316,12 @@ void SMESHGUI_NodesDlg::SelectionIntoArgument() return ; } - if ( mySelection->SelectionMode() != 1 ) { + if ( mySelection->SelectionMode() != NodeSelection ) { SpinBox_X->SetValue(0.0) ; SpinBox_Y->SetValue(0.0) ; SpinBox_Z->SetValue(0.0) ; QAD_MessageBox::warn1 ( QAD_Application::getDesktop(), tr ("SMESH_WRN_WARNING"), - tr ("SMESH_WRN_SELECTIONMODE_NODES"), tr ("SMESH_BUT_YES") ); + tr ("SMESH_WRN_SELECTIONMODE_NODES"), tr ("SMESH_BUT_OK") ); return; } @@ -345,7 +345,7 @@ void SMESHGUI_NodesDlg::SelectionIntoArgument() Standard_Boolean result; SMESH_Actor* ac = myMeshGUI->FindActor( myMesh, result, true ); - vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( ac->DataSource ); + vtkUnstructuredGrid* ugrid = vtkUnstructuredGrid::SafeDownCast( ac->GetUnstructuredGrid() ); float *p0 = ugrid->GetPoint(idNodes[0]); SpinBox_X->SetValue( p0[0] ) ; diff --git a/src/SMESHGUI/SMESHGUI_OrientationElementsDlg.cxx b/src/SMESHGUI/SMESHGUI_OrientationElementsDlg.cxx index dbcc09c75..92b7101a5 100644 --- a/src/SMESHGUI/SMESHGUI_OrientationElementsDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_OrientationElementsDlg.cxx @@ -249,7 +249,7 @@ void SMESHGUI_OrientationElementsDlg::ClickOnOk() //================================================================================= void SMESHGUI_OrientationElementsDlg::ClickOnCancel() { - QAD_Application::getDesktop()->SetSelectionMode( 4 ); + QAD_Application::getDesktop()->SetSelectionMode( ActorSelection ); disconnect( mySelection, 0, this, 0 ); mySMESHGUI->ResetState() ; reject() ; @@ -275,9 +275,9 @@ void SMESHGUI_OrientationElementsDlg::SelectionIntoArgument() if(nbElements < 1) return ; - if ( mySelection->SelectionMode() != 3 ) { + if ( mySelection->SelectionMode() != FaceSelection ) { QAD_MessageBox::warn1 ( QAD_Application::getDesktop(), tr ("SMESH_WRN_WARNING"), - tr ("SMESH_WRN_SELECTIONMODE_ELEMENTS"), tr ("SMESH_BUT_YES") ); + tr ("SMESH_WRN_SELECTIONMODE_ELEMENTS"), tr ("SMESH_BUT_OK") ); return; } diff --git a/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx b/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx index 060834165..1989d2c14 100644 --- a/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx @@ -28,6 +28,7 @@ using namespace std; #include "SMESHGUI_Preferences_ScalarBarDlg.h" +#include "SMESHGUI.h" #include #include @@ -36,171 +37,695 @@ using namespace std; #include #include #include +#include #include #include #include -#include -#include -#include +#include +#include -/* - * Constructs a SMESHGUI_Preferences_ScalarBarDlg which is a child of 'parent', with the - * name 'name' and widget flags set to 'f' +#include +#include + +#include "QAD_SpinBoxDbl.h" +#include "QAD_Config.h" +#include "SALOME_Selection.h" +#include "SMESHGUI.h" +#include "SMESH_Actor.h" + +#define MINIMUM_WIDTH 70 +#define MARGIN_SIZE 11 +#define SPACING_SIZE 6 + +#define DEF_VER_X 0.01 +#define DEF_VER_Y 0.10 +#define DEF_VER_H 0.80 +#define DEF_VER_W 0.10 +#define DEF_HOR_X 0.20 +#define DEF_HOR_Y 0.01 +#define DEF_HOR_H 0.12 +#define DEF_HOR_W 0.60 + +// Only one instance is allowed +SMESHGUI_Preferences_ScalarBarDlg* SMESHGUI_Preferences_ScalarBarDlg::myDlg = 0; + +//================================================================================================= +/*! + * SMESHGUI_Preferences_ScalarBarDlg::ScalarBarProperties + * + * Gets the only instance of "Scalar Bar Properties" dialog box + */ +//================================================================================================= +void SMESHGUI_Preferences_ScalarBarDlg::ScalarBarProperties(QWidget* parent, + SALOME_Selection* Sel) +{ + if ( !myDlg ) { + myDlg = new SMESHGUI_Preferences_ScalarBarDlg( parent, Sel, false ); + myDlg->show(); + } + else { + myDlg->show(); + myDlg->setActiveWindow(); + myDlg->raise(); + myDlg->setFocus(); + } +} + +//================================================================================================= +/*! + * SMESHGUI_Preferences_ScalarBarDlg::ScalarBarPreferences + * + * Opens "Scalar Bar Preferences" dialog box + */ +//================================================================================================= +void SMESHGUI_Preferences_ScalarBarDlg::ScalarBarPreferences( QWidget* parent ) +{ + SMESHGUI_Preferences_ScalarBarDlg* aDlg = new SMESHGUI_Preferences_ScalarBarDlg( parent, 0, true ); + aDlg->exec(); +} + +//================================================================================================= +/*! + * SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg * - * The dialog will by default be modeless, unless you set 'modal' to - * TRUE to construct a modal dialog. + * Constructor */ -SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( QWidget* parent, const char* name, bool modal, WFlags fl ) - : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ) +//================================================================================================= +SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg(QWidget* parent, + SALOME_Selection* Sel, + bool modal) + : QDialog( parent, 0, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose ) { - if ( !name ) - setName( "SMESHGUI_Preferences_ScalarBarDlg" ); - setCaption( tr( "SMESH_PREFERENCES_SCALARBAR" ) ); - setSizeGripEnabled( TRUE ); - - grid = new QGridLayout( this ); - grid->setSpacing( 6 ); - grid->setMargin( 11 ); - - /******************************************************************************/ - Properties = new QGroupBox( this, "Properties" ); - Properties->setTitle( tr( "SMESH_PROPERTIES" ) ); - Properties->setColumnLayout(0, Qt::Vertical ); - Properties->layout()->setSpacing( 0 ); - Properties->layout()->setMargin( 0 ); - grid_4 = new QGridLayout( Properties->layout() ); - grid_4->setAlignment( Qt::AlignTop ); - grid_4->setSpacing( 6 ); - grid_4->setMargin( 11 ); - - /* Font */ - grid_5 = new QGridLayout; - grid_5->setSpacing( 6 ); - grid_5->setMargin( 0 ); - TextLabel2 = new QLabel( Properties, "TextLabel2" ); - TextLabel2->setText( tr( "SMESH_FONT" ) ); - grid_5->addWidget( TextLabel2, 0, 0 ); - ComboBox1 = new QComboBox( FALSE, Properties, "ComboBox1" ); - ComboBox1->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); - ComboBox1->insertItem( tr( "SMESH_FONT_ARIAL" ) ); - ComboBox1->insertItem( tr( "SMESH_FONT_COURIER" ) ); - ComboBox1->insertItem( tr( "SMESH_FONT_TIMES" ) ); - grid_5->addWidget( ComboBox1, 0, 1 ); - grid_4->addLayout( grid_5, 0, 0 ); + setName( "SMESHGUI_Preferences_ScalarBarDlg" ); + setCaption( Sel ? tr( "SMESH_PROPERTIES_SCALARBAR" ) : tr( "SMESH_PREFERENCES_SCALARBAR" ) ); + setSizeGripEnabled( TRUE ); + + mySelection = Sel; + myActor = 0; + + /******************************************************************************/ + // Top layout + QGridLayout* aTopLayout = new QGridLayout( this ); + aTopLayout->setSpacing( SPACING_SIZE ); aTopLayout->setMargin( MARGIN_SIZE ); + int aRow = 0; + + /******************************************************************************/ + // Scalar range + if ( mySelection ) { + myRangeGrp = new QGroupBox ( tr( "SMESH_RANGE_SCALARBAR" ), this, "myRangeGrp" ); + myRangeGrp->setColumnLayout( 0, Qt::Vertical ); + myRangeGrp->layout()->setSpacing( 0 ); myRangeGrp->layout()->setMargin( 0 ); + QGridLayout* myRangeGrpLayout = new QGridLayout( myRangeGrp->layout() ); + myRangeGrpLayout->setAlignment( Qt::AlignTop ); + myRangeGrpLayout->setSpacing( SPACING_SIZE ); myRangeGrpLayout->setMargin( MARGIN_SIZE ); + + myMinEdit = new QLineEdit( myRangeGrp, "myMinEdit" ); + myMinEdit->setMinimumWidth( MINIMUM_WIDTH ); + myMinEdit->setValidator( new QDoubleValidator( this ) ); + + myMaxEdit = new QLineEdit( myRangeGrp, "myMaxEdit" ); + myMaxEdit->setMinimumWidth( MINIMUM_WIDTH ); + myMaxEdit->setValidator( new QDoubleValidator( this ) ); + + myRangeGrpLayout->addWidget( new QLabel( tr( "SMESH_RANGE_MIN" ), myRangeGrp, "myMinLab" ), 0, 0 ); + myRangeGrpLayout->addWidget( myMinEdit, 0, 1 ); + myRangeGrpLayout->addWidget( new QLabel( tr( "SMESH_RANGE_MAX" ), myRangeGrp, "myMaxLab" ), 0, 2 ); + myRangeGrpLayout->addWidget( myMaxEdit, 0, 3 ); + + aTopLayout->addWidget( myRangeGrp, aRow, 0 ); + aRow++; + } + + /******************************************************************************/ + // Text properties + myFontGrp = new QGroupBox ( tr( "SMESH_FONT_SCALARBAR" ), this, "myFontGrp" ); + myFontGrp->setColumnLayout( 0, Qt::Vertical ); + myFontGrp->layout()->setSpacing( 0 ); myFontGrp->layout()->setMargin( 0 ); + QGridLayout* myFontGrpLayout = new QGridLayout( myFontGrp->layout() ); + myFontGrpLayout->setAlignment( Qt::AlignTop ); + myFontGrpLayout->setSpacing( SPACING_SIZE ); myFontGrpLayout->setMargin( MARGIN_SIZE ); + + myTitleColorBtn = new QToolButton( myFontGrp, "myTitleColorBtn" ); + + myTitleFontCombo = new QComboBox( false, myFontGrp, "myTitleFontCombo" ); + myTitleFontCombo->setMinimumWidth( MINIMUM_WIDTH ); + myTitleFontCombo->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); + myTitleFontCombo->insertItem( tr( "SMESH_FONT_ARIAL" ) ); + myTitleFontCombo->insertItem( tr( "SMESH_FONT_COURIER" ) ); + myTitleFontCombo->insertItem( tr( "SMESH_FONT_TIMES" ) ); + + myTitleBoldCheck = new QCheckBox( tr( "SMESH_FONT_BOLD" ), myFontGrp, "myTitleBoldCheck" ); + myTitleItalicCheck = new QCheckBox( tr( "SMESH_FONT_ITALIC" ), myFontGrp, "myTitleItalicCheck" ); + myTitleShadowCheck = new QCheckBox( tr( "SMESH_FONT_SHADOW" ), myFontGrp, "myTitleShadowCheck" ); + + myLabelsColorBtn = new QToolButton( myFontGrp, "myLabelsColorBtn" ); + + myLabelsFontCombo = new QComboBox( false, myFontGrp, "myLabelsFontCombo" ); + myLabelsFontCombo->setMinimumWidth( MINIMUM_WIDTH ); + myLabelsFontCombo->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); + myLabelsFontCombo->insertItem( tr( "SMESH_FONT_ARIAL" ) ); + myLabelsFontCombo->insertItem( tr( "SMESH_FONT_COURIER" ) ); + myLabelsFontCombo->insertItem( tr( "SMESH_FONT_TIMES" ) ); + + myLabelsBoldCheck = new QCheckBox( tr( "SMESH_FONT_BOLD" ), myFontGrp, "myLabelsBoldCheck" ); + myLabelsItalicCheck = new QCheckBox( tr( "SMESH_FONT_ITALIC" ), myFontGrp, "myLabelsItalicCheck" ); + myLabelsShadowCheck = new QCheckBox( tr( "SMESH_FONT_SHADOW" ), myFontGrp, "myLabelsShadowCheck" ); + + myFontGrpLayout->addWidget( new QLabel( tr( "SMESH_TITLE" ), myFontGrp, "myFontTitleLab" ), 0, 0 ); + myFontGrpLayout->addWidget( myTitleColorBtn, 0, 1 ); + myFontGrpLayout->addWidget( myTitleFontCombo, 0, 2 ); + myFontGrpLayout->addWidget( myTitleBoldCheck, 0, 3 ); + myFontGrpLayout->addWidget( myTitleItalicCheck, 0, 4 ); + myFontGrpLayout->addWidget( myTitleShadowCheck, 0, 5 ); + + myFontGrpLayout->addWidget( new QLabel( tr( "SMESH_LABELS" ), myFontGrp, "myFontLabelsLab" ), 1, 0 ); + myFontGrpLayout->addWidget( myLabelsColorBtn, 1, 1 ); + myFontGrpLayout->addWidget( myLabelsFontCombo, 1, 2 ); + myFontGrpLayout->addWidget( myLabelsBoldCheck, 1, 3 ); + myFontGrpLayout->addWidget( myLabelsItalicCheck, 1, 4 ); + myFontGrpLayout->addWidget( myLabelsShadowCheck, 1, 5 ); + + aTopLayout->addWidget( myFontGrp, aRow, 0 ); + aRow++; + + /******************************************************************************/ + // Labels & Colors + myLabColorGrp = new QGroupBox ( tr( "SMESH_LABELS_COLORS_SCALARBAR" ), this, "myLabColorGrp" ); + myLabColorGrp->setColumnLayout( 0, Qt::Vertical ); + myLabColorGrp->layout()->setSpacing( 0 ); myLabColorGrp->layout()->setMargin( 0 ); + QGridLayout* myLabColorGrpLayout = new QGridLayout( myLabColorGrp->layout() ); + myLabColorGrpLayout->setAlignment( Qt::AlignTop ); + myLabColorGrpLayout->setSpacing( SPACING_SIZE ); myLabColorGrpLayout->setMargin( MARGIN_SIZE ); + + myColorsSpin = new QSpinBox( 2, 256, 1, myLabColorGrp, "myColorsSpin" ); + myColorsSpin->setMinimumWidth( MINIMUM_WIDTH ); + myColorsSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); + + myLabelsSpin = new QSpinBox( 2, 65, 1, myLabColorGrp, "myLabelsSpin" ); + myLabelsSpin->setMinimumWidth( MINIMUM_WIDTH ); + myLabelsSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); + + myLabColorGrpLayout->addWidget( new QLabel( tr( "SMESH_NUMBEROFCOLORS" ), myLabColorGrp, "myNbColorLab" ), 0, 0 ); + myLabColorGrpLayout->addWidget( myColorsSpin, 0, 1 ); + myLabColorGrpLayout->addWidget( new QLabel( tr( "SMESH_NUMBEROFLABELS" ), myLabColorGrp, "myNbLabsLab" ), 0, 2 ); + myLabColorGrpLayout->addWidget( myLabelsSpin, 0, 3 ); + + aTopLayout->addWidget( myLabColorGrp, aRow, 0 ); + aRow++; + + /******************************************************************************/ + // Orientation + myOrientationGrp = new QButtonGroup ( tr( "SMESH_ORIENTATION" ), this, "myOrientationGrp" ); + myOrientationGrp->setColumnLayout( 0, Qt::Vertical ); + myOrientationGrp->layout()->setSpacing( 0 ); myOrientationGrp->layout()->setMargin( 0 ); + QGridLayout* myOrientationGrpLayout = new QGridLayout( myOrientationGrp->layout() ); + myOrientationGrpLayout->setAlignment( Qt::AlignTop ); + myOrientationGrpLayout->setSpacing( SPACING_SIZE ); myOrientationGrpLayout->setMargin( MARGIN_SIZE ); + + myVertRadioBtn = new QRadioButton( tr( "SMESH_VERTICAL" ), myOrientationGrp, "myVertRadioBtn" ); + myHorizRadioBtn = new QRadioButton( tr( "SMESH_HORIZONTAL" ), myOrientationGrp, "myHorizRadioBtn" ); + myVertRadioBtn->setChecked( true ); + + myOrientationGrpLayout->addWidget( myVertRadioBtn, 0, 0 ); + myOrientationGrpLayout->addWidget( myHorizRadioBtn, 0, 1 ); + + aTopLayout->addWidget( myOrientationGrp, aRow, 0 ); + aRow++; + + /******************************************************************************/ + // Position & Size + myOriginDimGrp = new QGroupBox ( tr( "SMESH_POSITION_SIZE_SCALARBAR" ), this, "myOriginDimGrp" ); + myOriginDimGrp->setColumnLayout( 0, Qt::Vertical ); + myOriginDimGrp->layout()->setSpacing( 0 ); myOriginDimGrp->layout()->setMargin( 0 ); + QGridLayout* myOriginDimGrpLayout = new QGridLayout( myOriginDimGrp->layout() ); + myOriginDimGrpLayout->setAlignment( Qt::AlignTop ); + myOriginDimGrpLayout->setSpacing( SPACING_SIZE ); myOriginDimGrpLayout->setMargin( MARGIN_SIZE ); - /* Font attributes */ - grid_6 = new QGridLayout; - grid_6->setSpacing( 6 ); - grid_6->setMargin( 0 ); - Bold = new QCheckBox( Properties, "Bold" ); - Bold->setText( tr( "SMESH_FONT_BOLD" ) ); - grid_6->addWidget( Bold, 0, 0 ); - Italic = new QCheckBox( Properties, "Italic" ); - Italic->setText( tr( "SMESH_FONT_ITALIC" ) ); - grid_6->addWidget( Italic, 0, 1 ); - Shadow = new QCheckBox( Properties, "Shadow" ); - Shadow->setText( tr( "SMESH_FONT_SHADOW" ) ); - grid_6->addWidget( Shadow, 0, 2 ); - grid_4->addLayout( grid_6, 1, 0 ); - - grid_7 = new QGridLayout; - grid_7->setSpacing( 6 ); - grid_7->setMargin( 0 ); - NumberColors = new QLabel( Properties, "NumberColors" ); - NumberColors->setText( tr( "SMESH_NUMBEROFCOLORS" ) ); - grid_7->addWidget( NumberColors, 0, 0 ); - SpinBoxColors = new QSpinBox( Properties, "SpinBoxColors" ); - SpinBoxColors->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); - SpinBoxColors->setMinValue( 1 ); - grid_7->addWidget( SpinBoxColors, 0, 1 ); - NumberLabels = new QLabel( Properties, "NumberLabels" ); - NumberLabels->setText( tr( "SMESH_NUMBEROFLABELS" ) ); - grid_7->addWidget( NumberLabels, 1, 0 ); - SpinBoxLabels = new QSpinBox( Properties, "SpinBoxLabels" ); - SpinBoxLabels->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); - SpinBoxLabels->setMinValue( 1 ); - grid_7->addWidget( SpinBoxLabels, 1, 1 ); - grid_4->addLayout( grid_7, 2, 0 ); - - grid->addWidget( Properties, 0, 0 ); - - /******************************************************************************/ - ButtonGroup_Orientation = new QButtonGroup( this, "ButtonGroup_Orientation" ); - ButtonGroup_Orientation->setTitle( tr( "SMESH_ORIENTATION" ) ); - ButtonGroup_Orientation->setColumnLayout(0, Qt::Vertical ); - ButtonGroup_Orientation->layout()->setSpacing( 0 ); - ButtonGroup_Orientation->layout()->setMargin( 0 ); - grid_2 = new QGridLayout( ButtonGroup_Orientation->layout() ); - grid_2->setAlignment( Qt::AlignTop ); - grid_2->setSpacing( 6 ); - grid_2->setMargin( 11 ); - RadioVert = new QRadioButton( ButtonGroup_Orientation, "RadioVert" ); - RadioVert->setText( tr( "SMESH_VERTICAL" ) ); - RadioHoriz = new QRadioButton( ButtonGroup_Orientation, "RadioHoriz" ); - RadioHoriz->setText( tr( "SMESH_HORIZONTAL" ) ); - grid_2->addWidget( RadioVert, 0, 0 ); - grid_2->addWidget( RadioHoriz, 0, 1 ); - - grid->addWidget( ButtonGroup_Orientation, 1, 0 ); - - /******************************************************************************/ - GroupBox5 = new QGroupBox( this, "GroupBox5" ); - GroupBox5->setTitle( tr( "SMESH_DIMENSIONS" ) ); - GroupBox5->setColumnLayout(0, Qt::Vertical ); - GroupBox5->layout()->setSpacing( 0 ); - GroupBox5->layout()->setMargin( 0 ); - grid_11 = new QGridLayout( GroupBox5->layout() ); - grid_11->setAlignment( Qt::AlignTop ); - grid_11->setSpacing( 6 ); - grid_11->setMargin( 11 ); - - LineEditWidth = new QLineEdit( GroupBox5, "LineEditWidth" ); - grid_11->addWidget( LineEditWidth, 0, 0 ); - Width = new QLabel( GroupBox5, "Width" ); - Width->setText( tr( "SMESH_WIDTH" ) ); - grid_11->addWidget( Width, 0, 1 ); - LineEditHeight = new QLineEdit( GroupBox5, "LineEditHeight" ); - grid_11->addWidget( LineEditHeight, 1, 0 ); - Height = new QLabel( GroupBox5, "Height" ); - Height->setText( tr( "SMESH_HEIGHT" ) ); - grid_11->addWidget( Height, 1, 1 ); - - grid->addWidget( GroupBox5, 2, 0 ); - - /***************************************************************/ - QGroupBox* GroupButtons = new QGroupBox( this, "GroupButtons" ); - GroupButtons->setGeometry( QRect( 10, 10, 281, 48 ) ); - GroupButtons->setTitle( tr( "" ) ); - GroupButtons->setColumnLayout(0, Qt::Vertical ); - GroupButtons->layout()->setSpacing( 0 ); - GroupButtons->layout()->setMargin( 0 ); - grid_15 = new QGridLayout( GroupButtons->layout() ); - grid_15->setAlignment( Qt::AlignTop ); - grid_15->setSpacing( 6 ); - grid_15->setMargin( 11 ); - buttonOk = new QPushButton( GroupButtons, "buttonOk" ); - buttonOk->setText( tr( "SMESH_BUT_OK" ) ); - buttonOk->setAutoDefault( TRUE ); - buttonOk->setDefault( TRUE ); - grid_15->addWidget( buttonOk, 0, 0 ); - grid_15->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 1 ); - buttonCancel = new QPushButton( GroupButtons, "buttonCancel" ); - buttonCancel->setText( tr( "SMESH_BUT_CANCEL" ) ); - buttonCancel->setAutoDefault( TRUE ); - grid_15->addWidget( buttonCancel, 0, 2 ); - - grid->addWidget( GroupButtons, 3, 0 ); - - // signals and slots connections - connect( buttonOk, SIGNAL( clicked() ), this, SLOT( accept() ) ); - connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( reject() ) ); + myXSpin = new QAD_SpinBoxDbl( myOriginDimGrp, 0.0, 1.0, 0.1 ); + myXSpin->setMinimumWidth( MINIMUM_WIDTH ); + myXSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); + + myYSpin = new QAD_SpinBoxDbl( myOriginDimGrp, 0.0, 1.0, 0.1 ); + myYSpin->setMinimumWidth( MINIMUM_WIDTH ); + myYSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); + + myWidthSpin = new QAD_SpinBoxDbl( myOriginDimGrp, 0.0, 1.0, 0.1 ); + myWidthSpin->setMinimumWidth( MINIMUM_WIDTH ); + myWidthSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); + + myHeightSpin = new QAD_SpinBoxDbl( myOriginDimGrp, 0.0, 1.0, 0.1 ); + myHeightSpin->setMinimumWidth( MINIMUM_WIDTH ); + myHeightSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); + + myOriginDimGrpLayout->addWidget( new QLabel( tr( "SMESH_X_SCALARBAR" ), myOriginDimGrp, "myXLab" ), 0, 0 ); + myOriginDimGrpLayout->addWidget( myXSpin, 0, 1 ); + myOriginDimGrpLayout->addWidget( new QLabel( tr( "SMESH_Y_SCALARBAR" ), myOriginDimGrp, "myYLab" ), 0, 2 ); + myOriginDimGrpLayout->addWidget( myYSpin, 0, 3 ); + myOriginDimGrpLayout->addWidget( new QLabel( tr( "SMESH_WIDTH" ), myOriginDimGrp, "myWidthLab" ), 1, 0 ); + myOriginDimGrpLayout->addWidget( myWidthSpin, 1, 1 ); + myOriginDimGrpLayout->addWidget( new QLabel( tr( "SMESH_HEIGHT" ), myOriginDimGrp, "myHeightLab" ), 1, 2 ); + myOriginDimGrpLayout->addWidget( myHeightSpin, 1, 3 ); + + aTopLayout->addWidget( myOriginDimGrp, aRow, 0 ); + aRow++; + + /***************************************************************/ + // Common buttons + myButtonGrp = new QGroupBox( this, "myButtonGrp" ); + myButtonGrp->setColumnLayout(0, Qt::Vertical ); + myButtonGrp->layout()->setSpacing( 0 ); myButtonGrp->layout()->setMargin( 0 ); + QHBoxLayout* myButtonGrpLayout = new QHBoxLayout( myButtonGrp->layout() ); + myButtonGrpLayout->setAlignment( Qt::AlignTop ); + myButtonGrpLayout->setSpacing( SPACING_SIZE ); myButtonGrpLayout->setMargin( MARGIN_SIZE ); + + myOkBtn = new QPushButton( tr( "SMESH_BUT_OK" ), myButtonGrp, "myOkBtn" ); + myOkBtn->setAutoDefault( TRUE ); myOkBtn->setDefault( TRUE ); + myButtonGrpLayout->addWidget( myOkBtn ); + if ( mySelection ) { + myApplyBtn = new QPushButton( tr( "SMESH_BUT_APPLY" ), myButtonGrp, "myApplyBtn" ); + myApplyBtn->setAutoDefault( TRUE ); + myButtonGrpLayout->addWidget( myApplyBtn ); + } + myButtonGrpLayout->addStretch(); + myCancelBtn = new QPushButton( tr( "SMESH_BUT_CANCEL" ), myButtonGrp, "myCancelBtn" ); + if ( mySelection ) + myCancelBtn->setText( tr( "SMESH_BUT_CLOSE" ) ); + myCancelBtn->setAutoDefault( TRUE ); + myButtonGrpLayout->addWidget( myCancelBtn ); + + aTopLayout->addWidget( myButtonGrp, aRow, 0 ); + + /***************************************************************/ + // Init + // --> first init from preferences + QColor titleColor( 255, 255, 255 ); + if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarTitleColor" ) ) { + QStringList aTColor = QStringList::split( ":", QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleColor" ), false ); + titleColor = QColor( ( aTColor.count() > 0 ? aTColor[0].toInt() : 255 ), + ( aTColor.count() > 1 ? aTColor[1].toInt() : 255 ), + ( aTColor.count() > 2 ? aTColor[2].toInt() : 255 ) ); + } + myTitleColorBtn->setPaletteBackgroundColor( titleColor ); + myTitleFontCombo->setCurrentItem( 0 ); + if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarTitleFont" ) ) { + if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleFont" ) == "Arial" ) + myTitleFontCombo->setCurrentItem( 0 ); + if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleFont" ) == "Courier" ) + myTitleFontCombo->setCurrentItem( 1 ); + if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleFont" ) == "Times" ) + myTitleFontCombo->setCurrentItem( 2 ); + } + myTitleBoldCheck->setChecked( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleBold" ) == "true" ); + myTitleItalicCheck->setChecked( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleItalic" ) == "true" ); + myTitleShadowCheck->setChecked( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleShadow" ) == "true" ); + + QColor labelColor( 255, 255, 255 ); + if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarLabelColor" ) ) { + QStringList aLColor = QStringList::split( ":", QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelColor" ), false ); + labelColor = QColor( ( aLColor.count() > 0 ? aLColor[0].toInt() : 255 ), + ( aLColor.count() > 1 ? aLColor[1].toInt() : 255 ), + ( aLColor.count() > 2 ? aLColor[2].toInt() : 255 ) ); + } + myLabelsColorBtn->setPaletteBackgroundColor( labelColor ); + myLabelsFontCombo->setCurrentItem( 0 ); + if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarLabelFont" ) ) { + if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelFont" ) == "Arial" ) + myLabelsFontCombo->setCurrentItem( 0 ); + if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelFont" ) == "Courier" ) + myLabelsFontCombo->setCurrentItem( 1 ); + if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelFont" ) == "Times" ) + myLabelsFontCombo->setCurrentItem( 2 ); + } + myLabelsBoldCheck->setChecked( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelBold" ) == "true" ); + myLabelsItalicCheck->setChecked( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelItalic" ) == "true" ); + myLabelsShadowCheck->setChecked( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelShadow" ) == "true" ); + + int aNbColors = 64; + if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarNbOfColors" ) ) + aNbColors = QAD_CONFIG->getSetting( "SMESH:ScalarBarNbOfColors" ).toInt(); + myColorsSpin->setValue( aNbColors ); + int aNbLabels = 5; + if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarNbOfLabels" ) ) + aNbLabels = QAD_CONFIG->getSetting( "SMESH:ScalarBarNbOfLabels" ).toInt(); + myLabelsSpin->setValue( aNbLabels ); + + QString aOrientation = QAD_CONFIG->getSetting( "SMESH:ScalarBarOrientation" ); + if ( aOrientation == "Horizontal" ) + myHorizRadioBtn->setChecked( true ); + else + myVertRadioBtn->setChecked( true ); + myIniOrientation = myVertRadioBtn->isChecked(); + + if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarXPosition" ) ) + myIniX = QAD_CONFIG->getSetting( "SMESH:ScalarBarXPosition" ).toDouble(); + else + myIniX = myHorizRadioBtn->isChecked() ? DEF_HOR_X : DEF_VER_X; + if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarYPosition" ) ) + myIniY = QAD_CONFIG->getSetting( "SMESH:ScalarBarYPosition" ).toDouble(); + else + myIniY = myHorizRadioBtn->isChecked() ? DEF_HOR_Y : DEF_VER_Y; + if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarWidth" ) ) + myIniW = QAD_CONFIG->getSetting( "SMESH:ScalarBarWidth" ).toDouble(); + else + myIniW = myHorizRadioBtn->isChecked() ? DEF_HOR_W : DEF_VER_W; + if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarHeight" ) ) + myIniH = QAD_CONFIG->getSetting( "SMESH:ScalarBarHeight" ).toDouble(); + else + myIniH = myHorizRadioBtn->isChecked() ? DEF_HOR_H : DEF_VER_H; + setOriginAndSize( myIniX, myIniY, myIniW, myIniH ); + + if ( mySelection ) { + // --> then init from selection if necessary + onSelectionChanged(); + } + + /***************************************************************/ + // Connect section + connect( myTitleColorBtn, SIGNAL( clicked() ), this, SLOT( onTitleColor() ) ); + connect( myLabelsColorBtn, SIGNAL( clicked() ), this, SLOT( onLabelsColor() ) ); + connect( myOkBtn, SIGNAL( clicked() ), this, SLOT( onOk() ) ); + connect( myCancelBtn, SIGNAL( clicked() ), this, SLOT( onCancel() ) ); + connect( myXSpin, SIGNAL( valueChanged( double ) ), this, SLOT( onXYChanged() ) ); + connect( myYSpin, SIGNAL( valueChanged( double ) ), this, SLOT( onXYChanged() ) ); + connect( myOrientationGrp, SIGNAL( clicked( int ) ), this, SLOT( onOrientationChanged() ) ); + if ( mySelection ) { + connect( myApplyBtn, SIGNAL( clicked() ), this, SLOT( onApply() ) ); + connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( onSelectionChanged() ) ); + } + connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( onCancel() ) ) ; } -/* - * Destroys the object and frees any allocated resources +//================================================================================================= +/*! + * SMESHGUI_Preferences_ScalarBarDlg::~SMESHGUI_Preferences_ScalarBarDlg + * + * Destructor */ +//================================================================================================= SMESHGUI_Preferences_ScalarBarDlg::~SMESHGUI_Preferences_ScalarBarDlg() { - // no need to delete child widgets, Qt does it all for us } +//================================================================================================= +/*! + * SMESHGUI_Preferences_ScalarBarDlg::onOk + * + * OK button slot + */ +//================================================================================================= +void SMESHGUI_Preferences_ScalarBarDlg::onOk() +{ + if ( onApply() ) + onCancel(); +} + +//================================================================================================= +/*! + * SMESHGUI_Preferences_ScalarBarDlg::onApply + * + * Apply button slot + */ +//================================================================================================= +bool SMESHGUI_Preferences_ScalarBarDlg::onApply() +{ + if ( mySelection ) { + // Scalar Bar properties + if ( !myActor ) + return false; + vtkScalarBarActor* myScalarBarActor = myActor->GetScalarBarActor(); + + vtkTextProperty* aTitleTextPrp = myScalarBarActor->GetTitleTextProperty(); + QColor aTColor = myTitleColorBtn->paletteBackgroundColor(); + aTitleTextPrp->SetColor( aTColor.red()/255., aTColor.green()/255., aTColor.blue()/255. ); + if ( myTitleFontCombo->currentItem() == 0 ) + aTitleTextPrp->SetFontFamilyToArial(); + else if ( myTitleFontCombo->currentItem() == 1 ) + aTitleTextPrp->SetFontFamilyToCourier(); + else + aTitleTextPrp->SetFontFamilyToTimes(); + aTitleTextPrp->SetBold( myTitleBoldCheck->isChecked() ); + aTitleTextPrp->SetItalic( myTitleItalicCheck->isChecked() ); + aTitleTextPrp->SetShadow( myTitleShadowCheck->isChecked() ); + myScalarBarActor->SetTitleTextProperty( aTitleTextPrp ); + + vtkTextProperty* aLabelsTextPrp = myScalarBarActor->GetLabelTextProperty(); + QColor aLColor = myLabelsColorBtn->paletteBackgroundColor(); + aLabelsTextPrp->SetColor( aLColor.red()/255., aLColor.green()/255., aLColor.blue()/255. ); + if ( myLabelsFontCombo->currentItem() == 0 ) + aLabelsTextPrp->SetFontFamilyToArial(); + else if ( myLabelsFontCombo->currentItem() == 1 ) + aLabelsTextPrp->SetFontFamilyToCourier(); + else + aLabelsTextPrp->SetFontFamilyToTimes(); + aLabelsTextPrp->SetBold( myLabelsBoldCheck->isChecked() ); + aLabelsTextPrp->SetItalic( myLabelsItalicCheck->isChecked() ); + aLabelsTextPrp->SetShadow( myLabelsShadowCheck->isChecked() ); + myScalarBarActor->SetLabelTextProperty( aLabelsTextPrp ); + + myScalarBarActor->SetNumberOfLabels( myLabelsSpin->value() ); + myScalarBarActor->SetMaximumNumberOfColors( myColorsSpin->value() ); + + if ( myHorizRadioBtn->isChecked() ) + myScalarBarActor->SetOrientationToHorizontal(); + else + myScalarBarActor->SetOrientationToVertical(); + + myScalarBarActor->SetPosition( myXSpin->value(), myYSpin->value() ); + myScalarBarActor->SetWidth( myWidthSpin->value() ); + myScalarBarActor->SetHeight( myHeightSpin->value() ); + + double aMin = myMinEdit->text().toDouble(); + double aMax = myMaxEdit->text().toDouble(); + myScalarBarActor->GetLookupTable()->SetRange( aMin, aMax ); + SMESHGUI::GetSMESHGUI()->UpdateView(); + } + else { + // Scalar Bar preferences + QColor titleColor = myTitleColorBtn->paletteBackgroundColor(); + QAD_CONFIG->addSetting( "SMESH:ScalarBarTitleColor", QString().sprintf( "%d:%d:%d", titleColor.red(), titleColor.green(), titleColor.blue() ) ); + if ( myTitleFontCombo->currentItem() == 0 ) + QAD_CONFIG->addSetting( "SMESH:ScalarBarTitleFont", "Arial" ); + else if ( myTitleFontCombo->currentItem() == 1 ) + QAD_CONFIG->addSetting( "SMESH:ScalarBarTitleFont", "Courier" ); + else + QAD_CONFIG->addSetting( "SMESH:ScalarBarTitleFont", "Times" ); + QAD_CONFIG->addSetting( "SMESH:ScalarBarTitleBold", myTitleBoldCheck->isChecked() ? "true" : "false" ); + QAD_CONFIG->addSetting( "SMESH:ScalarBarTitleItalic", myTitleItalicCheck->isChecked() ? "true" : "false" ); + QAD_CONFIG->addSetting( "SMESH:ScalarBarTitleShadow", myTitleShadowCheck->isChecked() ? "true" : "false" ); + + QColor labelColor = myLabelsColorBtn->paletteBackgroundColor(); + QAD_CONFIG->addSetting( "SMESH:ScalarBarLabelColor", QString().sprintf( "%d:%d:%d", labelColor.red(), labelColor.green(),labelColor. blue() ) ); + if ( myLabelsFontCombo->currentItem() == 0 ) + QAD_CONFIG->addSetting( "SMESH:ScalarBarLabelFont", "Arial" ); + else if ( myLabelsFontCombo->currentItem() == 1 ) + QAD_CONFIG->addSetting( "SMESH:ScalarBarLabelFont", "Courier" ); + else + QAD_CONFIG->addSetting( "SMESH:ScalarBarLabelFont", "Times" ); + QAD_CONFIG->addSetting( "SMESH:ScalarBarLabelBold", myLabelsBoldCheck->isChecked() ? "true" : "false" ); + QAD_CONFIG->addSetting( "SMESH:ScalarBarLabelItalic", myLabelsItalicCheck->isChecked() ? "true" : "false" ); + QAD_CONFIG->addSetting( "SMESH:ScalarBarLabelShadow", myLabelsShadowCheck->isChecked() ? "true" : "false" ); + + QAD_CONFIG->addSetting( "SMESH:ScalarBarNbOfColors", myColorsSpin->value() ); + QAD_CONFIG->addSetting( "SMESH:ScalarBarNbOfLabels", myLabelsSpin->value() ); + + QAD_CONFIG->addSetting( "SMESH:ScalarBarOrientation", myHorizRadioBtn->isChecked() ? "Horizontal" : "Vertical" ); + + QAD_CONFIG->addSetting( "SMESH:ScalarBarXPosition", myXSpin->value() ); + QAD_CONFIG->addSetting( "SMESH:ScalarBarYPosition", myYSpin->value() ); + QAD_CONFIG->addSetting( "SMESH:ScalarBarWidth", myWidthSpin->value() ); + QAD_CONFIG->addSetting( "SMESH:ScalarBarHeight", myHeightSpin->value() ); + } + return true; +} + +//================================================================================================= +/*! + * SMESHGUI_Preferences_ScalarBarDlg::onCancel + * + * Cancel button slot + */ +//================================================================================================= +void SMESHGUI_Preferences_ScalarBarDlg::onCancel() +{ + close(); +} + +//================================================================================================= +/*! + * SMESHGUI_Preferences_ScalarBarDlg::onTitleColor + * + * Change Title color button slot + */ +//================================================================================================= +void SMESHGUI_Preferences_ScalarBarDlg::onTitleColor() +{ + QColor aColor = myTitleColorBtn->paletteBackgroundColor(); + aColor = QColorDialog::getColor( aColor, this ); + if ( aColor.isValid() ) + myTitleColorBtn->setPaletteBackgroundColor( aColor ); +} + +//================================================================================================= +/*! + * SMESHGUI_Preferences_ScalarBarDlg::onLabelsColor + * + * Change Labels color button slot + */ +//================================================================================================= +void SMESHGUI_Preferences_ScalarBarDlg::onLabelsColor() +{ + QColor aColor = myLabelsColorBtn->paletteBackgroundColor(); + aColor = QColorDialog::getColor( aColor, this ); + if ( aColor.isValid() ) + myLabelsColorBtn->setPaletteBackgroundColor( aColor ); +} + +//================================================================================================= +/*! + * SMESHGUI_Preferences_ScalarBarDlg::onSelectionChanged + * + * Called when selection changed + */ +//================================================================================================= +void SMESHGUI_Preferences_ScalarBarDlg::onSelectionChanged() +{ + if( mySelection ) { + if ( mySelection->IObjectCount() == 1 ) { + Handle(SALOME_InteractiveObject) anIO = mySelection->firstIObject(); + if( anIO->hasEntry() ) { + Standard_Boolean isOk; + SMESH_Actor* anActor = SMESHGUI::GetSMESHGUI()->FindActorByEntry( anIO->getEntry(), isOk, true ); + if ( isOk && anActor->GetScalarBarActor() && anActor->GetControlMode() != SMESH_Actor::eNone ) { + myActor = anActor; + vtkScalarBarActor* myScalarBarActor = myActor->GetScalarBarActor(); + + double aMin = 0.0, aMax = 0.0; + if ( myScalarBarActor->GetLookupTable() ) { + float *range = myScalarBarActor->GetLookupTable()->GetRange(); + myMinEdit->setText( QString::number( range[0] ) ); + myMaxEdit->setText( QString::number( range[1] ) ); + } + + vtkTextProperty* aTitleTextPrp = myScalarBarActor->GetTitleTextProperty(); + float aTColor[3]; + aTitleTextPrp->GetColor( aTColor ); + myTitleColorBtn->setPaletteBackgroundColor( QColor( (int)( aTColor[0]*255 ), (int)( aTColor[1]*255 ), (int)( aTColor[2]*255 ) ) ); + myTitleFontCombo->setCurrentItem( aTitleTextPrp->GetFontFamily() ); + myTitleBoldCheck->setChecked( aTitleTextPrp->GetBold() ); + myTitleItalicCheck->setChecked( aTitleTextPrp->GetItalic() ); + myTitleShadowCheck->setChecked( aTitleTextPrp->GetShadow() ); + + vtkTextProperty* aLabelsTextPrp = myScalarBarActor->GetLabelTextProperty(); + float aLColor[3]; + aLabelsTextPrp->GetColor( aLColor ); + myLabelsColorBtn->setPaletteBackgroundColor( QColor( (int)( aLColor[0]*255 ), (int)( aLColor[1]*255 ), (int)( aLColor[2]*255 ) ) ); + myLabelsFontCombo->setCurrentItem( aLabelsTextPrp->GetFontFamily() ); + myLabelsBoldCheck->setChecked( aLabelsTextPrp->GetBold() ); + myLabelsItalicCheck->setChecked( aLabelsTextPrp->GetItalic() ); + myLabelsShadowCheck->setChecked( aLabelsTextPrp->GetShadow() ); + + myLabelsSpin->setValue( myScalarBarActor->GetNumberOfLabels() ); + myColorsSpin->setValue( myScalarBarActor->GetMaximumNumberOfColors() ); + + if ( myScalarBarActor->GetOrientation() == VTK_ORIENT_VERTICAL ) + myVertRadioBtn->setChecked( true ); + else + myHorizRadioBtn->setChecked( true ); + myIniOrientation = myVertRadioBtn->isChecked(); + + myIniX = myScalarBarActor->GetPosition()[0]; + myIniY = myScalarBarActor->GetPosition()[1]; + myIniW = myScalarBarActor->GetWidth(); + myIniH = myScalarBarActor->GetHeight(); + setOriginAndSize( myIniX, myIniY, myIniW, myIniH ); + + myRangeGrp->setEnabled( true ); + myFontGrp->setEnabled( true ); + myLabColorGrp->setEnabled( true ); + myOrientationGrp->setEnabled( true ); + myOriginDimGrp->setEnabled( true ); + myOkBtn->setEnabled( true ); + myApplyBtn->setEnabled( true ); + return; + } + } + } + myActor = 0; + myRangeGrp->setEnabled( false ); + myFontGrp->setEnabled( false ); + myLabColorGrp->setEnabled( false ); + myOrientationGrp->setEnabled( false ); + myOriginDimGrp->setEnabled( false ); + myOkBtn->setEnabled( false ); + myApplyBtn->setEnabled( false ); + } +} + +//================================================================================================= +/*! + * SMESHGUI_Preferences_ScalarBarDlg::closeEvent + * + * Close event handler + */ +//================================================================================================= +void SMESHGUI_Preferences_ScalarBarDlg::closeEvent( QCloseEvent* e ) +{ + if ( mySelection ) // "Properties" dialog box + myDlg = 0; + QDialog::closeEvent( e ); +} + +//================================================================================================= +/*! + * SMESHGUI_Preferences_ScalarBarDlg::onXYChanged + * + * Called when X, Y values are changed + */ +//================================================================================================= +void SMESHGUI_Preferences_ScalarBarDlg::onXYChanged() +{ + myWidthSpin->setMaxValue( 1.0 - myXSpin->value() ); + myHeightSpin->setMaxValue( 1.0 - myYSpin->value() ); +} + +//================================================================================================= +/*! + * SMESHGUI_Preferences_ScalarBarDlg::setOriginAndSize + * + * Called when X, Y values are changed + */ +//================================================================================================= +void SMESHGUI_Preferences_ScalarBarDlg::setOriginAndSize( const double x, + const double y, + const double w, + const double h ) +{ + blockSignals( true ); + myXSpin->setValue( x ); + myYSpin->setValue( y ); + myWidthSpin->setMaxValue( 1.0 ); + myWidthSpin->setValue( w ); + myHeightSpin->setMaxValue( 1.0 ); + myHeightSpin->setValue( h ); + blockSignals( false ); + onXYChanged(); +} + +//================================================================================================= +/*! + * SMESHGUI_Preferences_ScalarBarDlg::onOrientationChanged + * + * Called when orientation is changed + */ +//================================================================================================= +void SMESHGUI_Preferences_ScalarBarDlg::onOrientationChanged() +{ + int aOrientation = myVertRadioBtn->isChecked(); + if ( aOrientation == myIniOrientation ) + setOriginAndSize( myIniX, myIniY, myIniW, myIniH ); + else + setOriginAndSize( aOrientation ? DEF_VER_X : DEF_HOR_X, + aOrientation ? DEF_VER_Y : DEF_HOR_Y, + aOrientation ? DEF_VER_W : DEF_HOR_W, + aOrientation ? DEF_VER_H : DEF_HOR_H ); +} diff --git a/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.h b/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.h index 777d24aff..bde914a36 100644 --- a/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.h +++ b/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.h @@ -29,11 +29,8 @@ #ifndef SMESHGUI_PREFERENCES_SCALARBARDLG_H #define SMESHGUI_PREFERENCES_SCALARBARDLG_H -#include #include -class QVBoxLayout; -class QHBoxLayout; -class QGridLayout; + class QButtonGroup; class QCheckBox; class QComboBox; @@ -41,54 +38,78 @@ class QGroupBox; class QLabel; class QLineEdit; class QPushButton; +class QToolButton; class QRadioButton; class QSpinBox; +class QAD_SpinBoxDbl; +class SALOME_Selection; +class SMESH_Actor; class SMESHGUI_Preferences_ScalarBarDlg : public QDialog { - Q_OBJECT + Q_OBJECT public: - SMESHGUI_Preferences_ScalarBarDlg( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); - ~SMESHGUI_Preferences_ScalarBarDlg(); - - QButtonGroup* ButtonGroup_Orientation; - QRadioButton* RadioHoriz; - QRadioButton* RadioVert; - QGroupBox* Properties; - QLabel* NumberLabels; - QLabel* NumberColors; - QSpinBox* SpinBoxLabels; - QSpinBox* SpinBoxColors; - QLabel* TextLabel2; - QComboBox* ComboBox1; - QCheckBox* Shadow; - QCheckBox* Italic; - QCheckBox* Bold; - QGroupBox* GroupBox5; - QLineEdit* LineEditWidth; - QLineEdit* LineEditHeight; - QLabel* Height; - QLabel* Width; - QPushButton* buttonCancel; - QPushButton* buttonOk; + ~SMESHGUI_Preferences_ScalarBarDlg(); + static void ScalarBarPreferences( QWidget* parent ); + static void ScalarBarProperties ( QWidget* parent, SALOME_Selection* Sel ); protected: - QGridLayout* grid; - QGridLayout* grid_2; - QGridLayout* grid_3; - QGridLayout* grid_4; - QGridLayout* grid_5; - QGridLayout* grid_6; - QGridLayout* grid_7; - QGridLayout* grid_8; - QGridLayout* grid_9; - QGridLayout* grid_10; - QGridLayout* grid_11; - QGridLayout* grid_12; - QGridLayout* grid_13; - QGridLayout* grid_14; - QGridLayout* grid_15; + SMESHGUI_Preferences_ScalarBarDlg( QWidget* parent = 0, SALOME_Selection* Sel = 0, bool modal = FALSE ); + static SMESHGUI_Preferences_ScalarBarDlg* myDlg; + void closeEvent( QCloseEvent* e ); + void setOriginAndSize( const double x, const double y, const double w, const double h ); + +protected slots: + void onOk(); + bool onApply(); + void onCancel(); + void onTitleColor(); + void onLabelsColor(); + void onSelectionChanged(); + void onXYChanged(); + void onOrientationChanged(); + +private: + SALOME_Selection* mySelection; + SMESH_Actor* myActor; + double myIniX, myIniY, myIniW, myIniH; + int myIniOrientation; + + QGroupBox* myRangeGrp; + QLineEdit* myMinEdit; + QLineEdit* myMaxEdit; + + QGroupBox* myFontGrp; + QToolButton* myTitleColorBtn; + QComboBox* myTitleFontCombo; + QCheckBox* myTitleBoldCheck; + QCheckBox* myTitleItalicCheck; + QCheckBox* myTitleShadowCheck; + QToolButton* myLabelsColorBtn; + QComboBox* myLabelsFontCombo; + QCheckBox* myLabelsBoldCheck; + QCheckBox* myLabelsItalicCheck; + QCheckBox* myLabelsShadowCheck; + + QGroupBox* myLabColorGrp; + QSpinBox* myColorsSpin; + QSpinBox* myLabelsSpin; + + QButtonGroup* myOrientationGrp; + QRadioButton* myVertRadioBtn; + QRadioButton* myHorizRadioBtn; + + QGroupBox* myOriginDimGrp; + QAD_SpinBoxDbl* myXSpin; + QAD_SpinBoxDbl* myYSpin; + QAD_SpinBoxDbl* myWidthSpin; + QAD_SpinBoxDbl* myHeightSpin; + + QGroupBox* myButtonGrp; + QPushButton* myOkBtn; + QPushButton* myApplyBtn; + QPushButton* myCancelBtn; }; #endif // SMESHGUI_PREFERENCES_SCALARBARDLG_H diff --git a/src/SMESHGUI/SMESHGUI_Preferences_SelectionDlg.cxx b/src/SMESHGUI/SMESHGUI_Preferences_SelectionDlg.cxx new file mode 100644 index 000000000..1f041af2e --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_Preferences_SelectionDlg.cxx @@ -0,0 +1,307 @@ +// SMESH SMESHGUI : GUI for SMESH component +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESHGUI_Preferences_SelectionDlg.cxx +// Author : Natalia KOPNOVA +// Module : SMESH +// $Header$ + +using namespace std; +#include "SMESHGUI_Preferences_SelectionDlg.h" +#include "SMESHGUI.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//================================================================================= +// class : SMESHGUI_LineEdit +// purpose : +//================================================================================= +SMESHGUI_LineEdit::SMESHGUI_LineEdit(QWidget* parent, const char *name) + : QLineEdit(parent, name) +{ +} + +SMESHGUI_LineEdit::SMESHGUI_LineEdit(const QString& text, QWidget* parent, const char *name) + : QLineEdit(text, parent, name) +{ +} + +void SMESHGUI_LineEdit::focusOutEvent(QFocusEvent* e) +{ + const QValidator* aVal = validator(); + QString aText = text(); + int aCurPos = cursorPosition(); + if (aVal && aVal->validate(aText, aCurPos) != QValidator::Acceptable) { + QString aValid = aText; + aVal->fixup(aValid); + if (aText != aValid) { + setText(aValid); + update(); + return; + } + } + QLineEdit::focusOutEvent(e); +} + + +//================================================================================= +// class : SMESHGUI_DoubleValidator +// purpose : +//================================================================================= +SMESHGUI_DoubleValidator::SMESHGUI_DoubleValidator(QObject * parent, const char *name) + : QDoubleValidator(parent, name) +{ +} + +SMESHGUI_DoubleValidator::SMESHGUI_DoubleValidator(double bottom, double top, int decimals, + QObject * parent, const char *name) + : QDoubleValidator(bottom, top, decimals, parent, name) +{ +} + +void SMESHGUI_DoubleValidator::fixup(QString& theText) const +{ + bool ok; + double aValue = theText.toDouble(&ok); + if (ok) { + if (aValue < bottom()) + theText = QString::number(bottom(), 'g', decimals()); + if (aValue > top()) + theText = QString::number(top(), 'g', decimals()); + } +} + + +//================================================================================= +// class : SMESHGUI_Preferences_SelectionDlg() +// purpose : +//================================================================================= +SMESHGUI_Preferences_SelectionDlg::SMESHGUI_Preferences_SelectionDlg( QWidget* parent, const char* name ) + : QDialog( parent, name, true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ) +{ + if ( !name ) setName( "SMESHGUI_Preferences_SelectionDlg" ); + setCaption( tr( "SMESH_PREF_SELECTION" ) ); + + QVBoxLayout* aMainLayout = new QVBoxLayout(this, 11, 6); + QLabel* aLabel; + + /***************************************************************/ + QGroupBox* aSelectBox = new QGroupBox(4, Qt::Horizontal, this, "selection"); + aSelectBox->setTitle(tr("SMESH_SELECTION")); + + aLabel = new QLabel(aSelectBox, "selection color label"); + aLabel->setText(tr("SMESH_OUTLINE_COLOR")); + myColor[2] = new QPushButton(aSelectBox, "outline color"); + myColor[2]->setFixedSize(QSize(25, 25)); + + aSelectBox->addSpace(0); + aSelectBox->addSpace(0); + + aLabel = new QLabel(aSelectBox, "selection color label"); + aLabel->setText(tr("SMESH_ELEMENTS_COLOR")); + myColor[1] = new QPushButton(aSelectBox, "elements color"); + myColor[1]->setFixedSize(QSize(25, 25)); + + aLabel = new QLabel(aSelectBox, "selection width label"); + aLabel->setText(tr("SMESH_WIDTH")); + myWidth[1] = new QSpinBox(0, 5, 1, aSelectBox, "selection width"); + myWidth[1]->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); + myWidth[1]->setButtonSymbols(QSpinBox::PlusMinus); + myWidth[1]->setMinimumWidth(50); + + /***************************************************************/ + QGroupBox* aPreSelectBox = new QGroupBox(1, Qt::Vertical, this, "preselection"); + aPreSelectBox->setTitle(tr("SMESH_PRESELECTION")); + + aLabel = new QLabel(aPreSelectBox, "preselection color label"); + aLabel->setText(tr("SMESH_HILIGHT_COLOR")); + myColor[0] = new QPushButton(aPreSelectBox, "preselection color"); + myColor[0]->setFixedSize(QSize(25, 25)); + + aLabel = new QLabel(aPreSelectBox, "preselection width label"); + aLabel->setText(tr("SMESH_WIDTH")); + myWidth[0] = new QSpinBox(0, 5, 1, aPreSelectBox, "preselection width"); + myWidth[0]->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); + myWidth[0]->setButtonSymbols(QSpinBox::PlusMinus); + myWidth[0]->setMinimumWidth(50); + + /***************************************************************/ + QGroupBox* aPrecisionBox = new QGroupBox(1, Qt::Vertical, this, "preselection"); + aPrecisionBox->setTitle(tr("SMESH_PRECISION")); + QDoubleValidator* aValidator = new SMESHGUI_DoubleValidator(aPrecisionBox); + aValidator->setBottom(0.001); + aValidator->setDecimals(6); + + aLabel = new QLabel(aPrecisionBox, "node tol label"); + aLabel->setText(tr("SMESH_NODES")); + myPrecision[0] = new SMESHGUI_LineEdit(aPrecisionBox, "node precision"); + myPrecision[0]->setValidator(aValidator); + + aLabel = new QLabel(aPrecisionBox, "item tol label"); + aLabel->setText(tr("SMESH_ELEMENTS")); + myPrecision[1] = new SMESHGUI_LineEdit(aPrecisionBox, "item precision"); + myPrecision[1]->setValidator(aValidator); + + /***************************************************************/ + QFrame* aButtons = new QFrame(this, "button box"); + aButtons->setFrameStyle(QFrame::Box | QFrame::Sunken); + QHBoxLayout* aBtnLayout = new QHBoxLayout(aButtons, 11, 6); + aBtnLayout->setAutoAdd(false); + + QPushButton* aOKBtn = new QPushButton(aButtons, "ok"); + aOKBtn->setText(tr("SMESH_BUT_OK")); + aOKBtn->setAutoDefault(true); + aOKBtn->setDefault(true); + QPushButton* aCloseBtn = new QPushButton(aButtons, "close"); + aCloseBtn->setText(tr("SMESH_BUT_CLOSE")); + aCloseBtn->setAutoDefault(true); + + aBtnLayout->addWidget(aOKBtn); + aBtnLayout->addStretch(); + aBtnLayout->addWidget(aCloseBtn); + + /***************************************************************/ + aMainLayout->addWidget(aSelectBox); + aMainLayout->addWidget(aPreSelectBox); + aMainLayout->addWidget(aPrecisionBox); + aMainLayout->addWidget(aButtons); + + for (int i = 0; i < 3; i++) + connect(myColor[i], SIGNAL(clicked()), this, SLOT(onSelectColor())); + + connect(aOKBtn, SIGNAL(clicked()), this, SLOT(accept())); + connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(reject())); + + /* Move widget on the botton right corner of main widget */ + int x, y ; + SMESHGUI::GetSMESHGUI()->DefineDlgPosition(this, x, y); + this->move(x, y); +} + +//================================================================================= +// function : ~SMESHGUI_Preferences_SelectionDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +SMESHGUI_Preferences_SelectionDlg::~SMESHGUI_Preferences_SelectionDlg() +{ + // no need to delete child widgets, Qt does it all for us +} + +//================================================================================= +// function : closeEvent() +// purpose : +//================================================================================= +void SMESHGUI_Preferences_SelectionDlg::closeEvent( QCloseEvent* e ) +{ + reject(); +} + +//================================================================================= +// function : onSelectColor() +// purpose : +//================================================================================= +void SMESHGUI_Preferences_SelectionDlg::onSelectColor() +{ + QPushButton* aSender = (QPushButton*)sender(); + QColor aColor = aSender->palette().active().button(); + aColor = QColorDialog::getColor(aColor, this); + if (aColor.isValid()) { + QPalette aPal = aSender->palette(); + aPal.setColor(QColorGroup::Button, aColor); + aSender->setPalette(aPal); + } +} + +//================================================================================= +// function : SetColor() +// purpose : +//================================================================================= +void SMESHGUI_Preferences_SelectionDlg::SetColor(int type, QColor color) +{ + if (type > 0 && type <= 3) { + QPalette aPal = myColor[type-1]->palette(); + aPal.setColor(QColorGroup::Button, color); + myColor[type-1]->setPalette(aPal); + } +} + +//================================================================================= +// function : GetColor() +// purpose : +//================================================================================= +QColor SMESHGUI_Preferences_SelectionDlg::GetColor(int type) +{ + QColor aColor; + if (type > 0 && type <= 3) + aColor = myColor[type-1]->palette().active().button(); + return aColor; +} + +//================================================================================= +// function : SetWidth() +// purpose : +//================================================================================= +void SMESHGUI_Preferences_SelectionDlg::SetWidth(int type, int value) +{ + if (type > 0 && type <= 2) + myWidth[type-1]->setValue(value); +} + +//================================================================================= +// function : GetWidth() +// purpose : +//================================================================================= +int SMESHGUI_Preferences_SelectionDlg::GetWidth(int type) +{ + if (type > 0 && type <= 2) + return myWidth[type-1]->value(); + return 0; +} + +//================================================================================= +// function : SetPrecision() +// purpose : +//================================================================================= +void SMESHGUI_Preferences_SelectionDlg::SetPrecision(int type, double value) +{ + if (type > 0 && type <= 2) + myPrecision[type-1]->setText(QString::number(value)); +} + +//================================================================================= +// function : GetPrecision() +// purpose : +//================================================================================= +double SMESHGUI_Preferences_SelectionDlg::GetPrecision(int type) +{ + if (type > 0 && type <= 2) + return myPrecision[type-1]->text().toDouble(); +} diff --git a/src/SMESHGUI/SMESHGUI_Preferences_SelectionDlg.h b/src/SMESHGUI/SMESHGUI_Preferences_SelectionDlg.h new file mode 100644 index 000000000..a4edd3865 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_Preferences_SelectionDlg.h @@ -0,0 +1,97 @@ +// SMESH SMESHGUI : GUI for SMESH component +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platorm.org or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESHGUI_Preferences_SelectionDlg.h +// Author : Natalia KOPNOVA +// Module : SMESH +// $Header$ + +#ifndef SMESHGUI_PREFERENCES_SELECTIONDLG_H +#define SMESHGUI_PREFERENCES_SELECTIONDLG_H + + +// QT Includes +#include +#include +#include + +class QPushButton; +class QSpinBox; +class QColor; + +class SMESHGUI_LineEdit : public QLineEdit +{ + Q_OBJECT + + public: + SMESHGUI_LineEdit(QWidget* parent, const char* name = 0); + SMESHGUI_LineEdit(const QString& text, QWidget* parent, const char* name = 0); + + ~SMESHGUI_LineEdit() {}; + + protected: + void focusOutEvent(QFocusEvent* e); +}; + +class SMESHGUI_DoubleValidator : public QDoubleValidator +{ + Q_OBJECT + + public: + SMESHGUI_DoubleValidator(QObject* parent, const char* name = 0); + SMESHGUI_DoubleValidator(double bottom, double top, int decimals, + QObject* parent, const char* name = 0); + + ~SMESHGUI_DoubleValidator() {}; + + void fixup(QString& text) const; +}; + +class SMESHGUI_Preferences_SelectionDlg : public QDialog +{ + Q_OBJECT + +public: + SMESHGUI_Preferences_SelectionDlg( QWidget* parent = 0, const char* name = 0 ); + ~SMESHGUI_Preferences_SelectionDlg(); + + void SetColor(int type, QColor color); + QColor GetColor(int type); + void SetWidth(int type, int value); + int GetWidth(int type); + void SetPrecision(int type, double value); + double GetPrecision(int type); + +private: + void closeEvent( QCloseEvent* e ) ; + +private slots: + void onSelectColor(); + +private: + QPushButton* myColor[3]; + QSpinBox* myWidth[2]; + QLineEdit* myPrecision[2]; +}; + +#endif // SMESHGUI_PREFERENCES_SELECTIONDLG_H diff --git a/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx b/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx index b15ea1b80..fd3e5e427 100644 --- a/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx @@ -247,7 +247,7 @@ void SMESHGUI_RemoveElementsDlg::ClickOnOk() //================================================================================= void SMESHGUI_RemoveElementsDlg::ClickOnCancel() { - QAD_Application::getDesktop()->SetSelectionMode( 4 ); + QAD_Application::getDesktop()->SetSelectionMode( ActorSelection ); disconnect( mySelection, 0, this, 0 ); mySMESHGUI->ResetState() ; reject() ; @@ -273,9 +273,9 @@ void SMESHGUI_RemoveElementsDlg::SelectionIntoArgument() if(nbElements < 1) return ; - if ( mySelection->SelectionMode() != 3 ) { + if ( mySelection->SelectionMode() != CellSelection ) { QAD_MessageBox::warn1 ( QAD_Application::getDesktop(), tr ("SMESH_WRN_WARNING"), - tr ("SMESH_WRN_SELECTIONMODE_ELEMENTS"), tr ("SMESH_BUT_YES") ); + tr ("SMESH_WRN_SELECTIONMODE_ELEMENTS"), tr ("SMESH_BUT_OK") ); return; } diff --git a/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx b/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx index 373cfbc51..68ba6b863 100644 --- a/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx @@ -251,7 +251,7 @@ void SMESHGUI_RemoveNodesDlg::ClickOnOk() //================================================================================= void SMESHGUI_RemoveNodesDlg::ClickOnCancel() { - QAD_Application::getDesktop()->SetSelectionMode( 4 ); + QAD_Application::getDesktop()->SetSelectionMode( ActorSelection ); disconnect( mySelection, 0, this, 0 ); mySMESHGUI->ResetState() ; mySMESHGUI->EraseSimulationActors(); @@ -278,9 +278,9 @@ void SMESHGUI_RemoveNodesDlg::SelectionIntoArgument() if(nbNodes < 1) return ; - if ( mySelection->SelectionMode() != 1 ){ + if ( mySelection->SelectionMode() != NodeSelection ){ QAD_MessageBox::warn1 ( QAD_Application::getDesktop(), tr ("SMESH_WRN_WARNING"), - tr ("SMESH_WRN_SELECTIONMODE_NODES"), tr ("SMESH_BUT_YES") ); + tr ("SMESH_WRN_SELECTIONMODE_NODES"), tr ("SMESH_BUT_OK") ); return; } diff --git a/src/SMESHGUI/SMESHGUI_StudyAPI.cxx b/src/SMESHGUI/SMESHGUI_StudyAPI.cxx index a205272d5..65605ad92 100644 --- a/src/SMESHGUI/SMESHGUI_StudyAPI.cxx +++ b/src/SMESHGUI/SMESHGUI_StudyAPI.cxx @@ -82,40 +82,8 @@ SMESHGUI_StudyAPI::SMESHGUI_StudyAPI () SMESHGUI_StudyAPI::SMESHGUI_StudyAPI ( SALOMEDS::Study_ptr aStudy, SMESH::SMESH_Gen_ptr CompMesh) { - myStudy = aStudy; - myStudyBuilder = aStudy->NewBuilder(); - setOrb(); - - // NRI : Temporary added - if ( myStudy->GetProperties()->IsLocked() ) { -// QAD_MessageBox::warn1 ( (QWidget*)QAD_Application::getDesktop(), -// QObject::tr("WARNING"), -// QObject::tr("WRN_STUDY_LOCKED"), -// QObject::tr("BUT_OK") ); - - return; - } - // NRI - - SALOMEDS::SComponent_var father = aStudy->FindComponent("MESH"); - /*SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::AttributeName_var aName; - SALOMEDS::AttributePixMap_var aPixmap; - - if (father->_is_nil()) { - father = myStudyBuilder->NewComponent("MESH"); - } - anAttr = myStudyBuilder->FindOrCreateAttribute(father, "AttributeName"); - aName = SALOMEDS::AttributeName::_narrow(anAttr); - //NRI aName->SetValue(QObject::tr("SMESH_MEN_COMPONENT")); - aName->SetValue( QAD_Application::getDesktop()->getComponentUserName( "SMESH" ) ); - anAttr = myStudyBuilder->FindOrCreateAttribute(father, "AttributePixMap"); - aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr); - aPixmap->SetPixMap( "ICON_OBJBROWSER_SMESH" ); - - myStudyBuilder->DefineComponentInstance(father, CompMesh ); - mySComponentMesh = SALOMEDS::SComponent::_narrow( father );*/ + Update( aStudy ); } //======================================================================= @@ -130,93 +98,12 @@ SMESHGUI_StudyAPI::~SMESHGUI_StudyAPI () // function : // purpose : Update //======================================================================= -void SMESHGUI_StudyAPI::Update(SMESH::SMESH_Gen_ptr CompMesh) -{ - // NRI : Temporary added - if ( myStudy->GetProperties()->IsLocked() ) { - return; - } - // NRI - - SALOMEDS::SComponent_var father = myStudy->FindComponent("MESH"); - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::AttributeName_var aName; - SALOMEDS::AttributePixMap_var aPixmap; - - if (father->_is_nil()) { - father = myStudyBuilder->NewComponent("MESH"); - anAttr = myStudyBuilder->FindOrCreateAttribute(father, "AttributeName"); - aName = SALOMEDS::AttributeName::_narrow(anAttr); - //NRI aName->SetValue(QObject::tr("SMESH_MEN_COMPONENT")); - aName->SetValue( QAD_Application::getDesktop()->getComponentUserName( "SMESH" ) ); - anAttr = myStudyBuilder->FindOrCreateAttribute(father, "AttributePixMap"); - aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr); - aPixmap->SetPixMap( "ICON_OBJBROWSER_SMESH" ); - } - myStudyBuilder->DefineComponentInstance(father, CompMesh ); - mySComponentMesh = SALOMEDS::SComponent::_narrow( father ); -} - -//======================================================================= -// function : AddNewMesh -// purpose : -//======================================================================= - -SALOMEDS::SObject_ptr SMESHGUI_StudyAPI::AddNewMesh (SMESH::SMESH_Mesh_ptr M) +void SMESHGUI_StudyAPI::Update(SALOMEDS::Study_ptr aStudy) { - // NRI : Temporary added - if ( myStudy->GetProperties()->IsLocked() ) { - return SALOMEDS::SObject::_nil(); - } - // NRI - - //Find or Create Hypothesis root - SALOMEDS::SObject_var HypothesisRoot; - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::AttributeName_var aName; - SALOMEDS::AttributeIOR_var anIOR; - SALOMEDS::AttributeSelectable_var aSelAttr; - SALOMEDS::AttributePixMap_var aPixmap; - - if (!mySComponentMesh->FindSubObject (Tag_HypothesisRoot, HypothesisRoot)) { - HypothesisRoot = myStudyBuilder->NewObjectToTag (mySComponentMesh, Tag_HypothesisRoot); - anAttr = myStudyBuilder->FindOrCreateAttribute(HypothesisRoot, "AttributeName"); - aName = SALOMEDS::AttributeName::_narrow(anAttr); - aName->SetValue(QObject::tr("SMESH_MEN_HYPOTHESIS")); - anAttr = myStudyBuilder->FindOrCreateAttribute(HypothesisRoot, "AttributePixMap"); - aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr); - aPixmap->SetPixMap( "ICON_SMESH_TREE_HYPO" ); - anAttr = myStudyBuilder->FindOrCreateAttribute(HypothesisRoot, "AttributeSelectable"); - aSelAttr = SALOMEDS::AttributeSelectable::_narrow(anAttr); - aSelAttr->SetSelectable(false); - } - - SALOMEDS::SObject_var AlgorithmsRoot; - if (!mySComponentMesh->FindSubObject (Tag_AlgorithmsRoot, AlgorithmsRoot)) { - AlgorithmsRoot = myStudyBuilder->NewObjectToTag (mySComponentMesh, Tag_AlgorithmsRoot); - anAttr = myStudyBuilder->FindOrCreateAttribute(AlgorithmsRoot, "AttributeName"); - aName = SALOMEDS::AttributeName::_narrow(anAttr); - aName->SetValue(QObject::tr("SMESH_MEN_ALGORITHMS")); - anAttr = myStudyBuilder->FindOrCreateAttribute(AlgorithmsRoot, "AttributePixMap"); - aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr); - aPixmap->SetPixMap( "ICON_SMESH_TREE_ALGO" ); - anAttr = myStudyBuilder->FindOrCreateAttribute(AlgorithmsRoot, "AttributeSelectable"); - aSelAttr = SALOMEDS::AttributeSelectable::_narrow(anAttr); - aSelAttr->SetSelectable(false); - } - - // Add New Mesh - SALOMEDS::SObject_var newMesh = myStudyBuilder->NewObject(mySComponentMesh); - anAttr = myStudyBuilder->FindOrCreateAttribute(newMesh, "AttributePixMap"); - aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr); - aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH" ); - anAttr = myStudyBuilder->FindOrCreateAttribute(newMesh, "AttributeIOR"); - anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - anIOR->SetValue(IORToString(M)); - return SALOMEDS::SObject::_narrow( newMesh ); + myStudy = SALOMEDS::Study::_duplicate( aStudy ); + myStudyBuilder = aStudy->NewBuilder(); } - //======================================================================= // function : SetShape // purpose : @@ -245,6 +132,9 @@ GEOM::GEOM_Shape_ptr SMESHGUI_StudyAPI::GetShapeOnMeshOrSubMesh(SALOMEDS::SObjec } // NRI + if ( SO_Mesh_Or_SubMesh->_is_nil() ) + return GEOM::GEOM_Shape::_nil(); + GEOM::GEOM_Shape_var Shape; SALOMEDS::SObject_var aSO, aGeom; SALOMEDS::GenericAttribute_var anAttr; @@ -260,112 +150,6 @@ GEOM::GEOM_Shape_ptr SMESHGUI_StudyAPI::GetShapeOnMeshOrSubMesh(SALOMEDS::SObjec return GEOM::GEOM_Shape::_nil(); } -//======================================================================= -// function : AddNewHypothesis -// purpose : -//======================================================================= -SALOMEDS::SObject_ptr SMESHGUI_StudyAPI::AddNewHypothesis (SMESH::SMESH_Hypothesis_ptr H) -{ - // NRI : Temporary added - if ( myStudy->GetProperties()->IsLocked() ) { - return SALOMEDS::SObject::_nil(); - } - // NRI - - //Find or Create Hypothesis root - SALOMEDS::SObject_var HypothesisRoot; - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::AttributeName_var aName; - SALOMEDS::AttributeIOR_var anIOR; - SALOMEDS::AttributeSelectable_var aSelAttr; - SALOMEDS::AttributePixMap_var aPixmap; - - if (!mySComponentMesh->FindSubObject (Tag_HypothesisRoot, HypothesisRoot)) { - HypothesisRoot = myStudyBuilder->NewObjectToTag (mySComponentMesh, Tag_HypothesisRoot); - anAttr = myStudyBuilder->FindOrCreateAttribute(HypothesisRoot, "AttributeName"); - aName = SALOMEDS::AttributeName::_narrow(anAttr); - aName->SetValue(QObject::tr("SMESH_MEN_HYPOTHESIS")); - anAttr = myStudyBuilder->FindOrCreateAttribute(HypothesisRoot, "AttributeSelectable"); - aSelAttr = SALOMEDS::AttributeSelectable::_narrow(anAttr); - aSelAttr->SetSelectable(false); - anAttr = myStudyBuilder->FindOrCreateAttribute(HypothesisRoot, "AttributePixMap"); - aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr); - aPixmap->SetPixMap( "ICON_SMESH_TREE_HYPO" ); - } - // Add New Hypothesis - SALOMEDS::SObject_var newHypo = myStudyBuilder->NewObject(HypothesisRoot); - anAttr = myStudyBuilder->FindOrCreateAttribute(newHypo, "AttributePixMap"); - aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr); - QString aType = H->GetName(); - MESSAGE ( " aType " << aType ) - aPixmap->SetPixMap( "ICON_SMESH_TREE_HYPO_" + aType ); - // if ( aType.compare("LocalLength") == 0 ) - // aPixmap->SetPixMap( "ICON_SMESH_TREE_HYPO_LENGTH" ); - // else if ( aType.compare("NumberOfSegments") == 0 ) - // aPixmap->SetPixMap( "ICON_SMESH_TREE_HYPO_SEGMENT" ); - // else if ( aType.compare("MaxElementArea") == 0 ) - // aPixmap->SetPixMap( "ICON_SMESH_TREE_HYPO_AREA" ); - // else if ( aType.compare("MaxElementVolume") == 0 ) - // aPixmap->SetPixMap( "ICON_SMESH_TREE_HYPO_VOLUME" ); - anAttr = myStudyBuilder->FindOrCreateAttribute(newHypo, "AttributeIOR"); - anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - anIOR->SetValue(IORToString(H)); - return SALOMEDS::SObject::_narrow(newHypo); -} - -//======================================================================= -// function : AddNewAlgorithms -// purpose : -//======================================================================= -SALOMEDS::SObject_ptr SMESHGUI_StudyAPI::AddNewAlgorithms (SMESH::SMESH_Hypothesis_ptr H) -{ - // NRI : Temporary added - if ( myStudy->GetProperties()->IsLocked() ) { - return SALOMEDS::SObject::_nil(); - } - // NRI - - //Find or Create Algorithms root - SALOMEDS::SObject_var AlgorithmsRoot; - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::AttributeName_var aName; - SALOMEDS::AttributeIOR_var anIOR; - SALOMEDS::AttributeSelectable_var aSelAttr; - SALOMEDS::AttributePixMap_var aPixmap; - - if (!mySComponentMesh->FindSubObject (Tag_AlgorithmsRoot, AlgorithmsRoot)) { - AlgorithmsRoot = myStudyBuilder->NewObjectToTag (mySComponentMesh, Tag_AlgorithmsRoot); - anAttr = myStudyBuilder->FindOrCreateAttribute(AlgorithmsRoot, "AttributeName"); - aName = SALOMEDS::AttributeName::_narrow(anAttr); - aName->SetValue(QObject::tr("SMESH_MEN_ALGORITHMS")); - anAttr = myStudyBuilder->FindOrCreateAttribute(AlgorithmsRoot, "AttributeSelectable"); - aSelAttr = SALOMEDS::AttributeSelectable::_narrow(anAttr); - aSelAttr->SetSelectable(false); - anAttr = myStudyBuilder->FindOrCreateAttribute(AlgorithmsRoot, "AttributePixMap"); - aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr); - aPixmap->SetPixMap( "ICON_SMESH_TREE_ALGO" ); - } - // Add New Algorithms - SALOMEDS::SObject_var newHypo = myStudyBuilder->NewObject(AlgorithmsRoot); - anAttr = myStudyBuilder->FindOrCreateAttribute(newHypo, "AttributePixMap"); - aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr); - QString aType = H->GetName(); - // if ( aType.compare("Regular_1D") == 0 ) - aPixmap->SetPixMap( "ICON_SMESH_TREE_ALGO_" + aType ); - // aPixmap->SetPixMap( "ICON_SMESH_TREE_ALGO_REGULAR" ); - // else if ( aType.compare("MEFISTO_2D") == 0 ) - // aPixmap->SetPixMap( "ICON_SMESH_TREE_ALGO_MEFISTO" ); - // else if ( aType.compare("Quadrangle_2D") == 0 ) - // aPixmap->SetPixMap( "ICON_SMESH_TREE_ALGO_QUAD" ); - // else if ( aType.compare("Hexa_3D") == 0 ) - // aPixmap->SetPixMap( "ICON_SMESH_TREE_ALGO_HEXA" ); - anAttr = myStudyBuilder->FindOrCreateAttribute(newHypo, "AttributeIOR"); - anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - anIOR->SetValue(IORToString(H)); - return SALOMEDS::SObject::_narrow(newHypo); -} - - //======================================================================= // function : AddSubMeshOnShape // purpose : @@ -512,46 +296,25 @@ void SMESHGUI_StudyAPI::SetAlgorithms (SALOMEDS::SObject_ptr SO_MorSM, // function : // purpose : //======================================================================= -SALOMEDS::SObject_ptr SMESHGUI_StudyAPI::FindMesh (SMESH::SMESH_Mesh_ptr M) +SALOMEDS::SObject_ptr SMESHGUI_StudyAPI::FindObject( CORBA::Object_ptr theObject ) { // NRI : Temporary added if ( myStudy->GetProperties()->IsLocked() ) { return SALOMEDS::SObject::_nil(); } // NRI - return SALOMEDS::SObject::_narrow( myStudy->FindObjectIOR (IORToString(M)) ); -} - -//======================================================================= -// function : -// purpose : -//======================================================================= -SALOMEDS::SObject_ptr SMESHGUI_StudyAPI::FindHypothesisOrAlgorithms (SMESH::SMESH_Hypothesis_ptr H) -{ - // NRI : Temporary added - if ( myStudy->GetProperties()->IsLocked() ) { - return SALOMEDS::SObject::_nil(); + if ( !CORBA::is_nil ( theObject ) ) { + string anIOR = IORToString( theObject ); + if ( anIOR != "" ) + return myStudy->FindObjectIOR( anIOR.c_str() ); } - // NRI - return SALOMEDS::SObject::_narrow( myStudy->FindObjectIOR (IORToString(H)) ); -} - + return SALOMEDS::SObject::_nil(); +} //======================================================================= // function : // purpose : //======================================================================= -SALOMEDS::SObject_ptr SMESHGUI_StudyAPI::FindSubMesh (SMESH::SMESH_subMesh_ptr SM) -{ - // NRI : Temporary added - if ( myStudy->GetProperties()->IsLocked() ) { - return SALOMEDS::SObject::_nil(); - } - // NRI - return SALOMEDS::SObject::_narrow( myStudy->FindObjectIOR (IORToString(SM)) ); -} - - void SMESHGUI_StudyAPI::setOrb() { try { @@ -565,25 +328,6 @@ void SMESHGUI_StudyAPI::setOrb() ASSERT(! CORBA::is_nil(_orb)); } -//======================================================================= -// function : -// purpose : -//======================================================================= -void SMESHGUI_StudyAPI::SetTagHypothesisRoot() -{ - // NRI : Temporary added - if ( myStudy->GetProperties()->IsLocked() ) { - return; - } - // NRI - SALOMEDS::ChildIterator_var it = myStudy->NewChildIterator(mySComponentMesh); - int i = 0; - for (; it->More();it->Next()) { - i++; - } - Tag_HypothesisRoot = i++; -} - //======================================================================= // function : // purpose : diff --git a/src/SMESHGUI/SMESHGUI_StudyAPI.h b/src/SMESHGUI/SMESHGUI_StudyAPI.h index 5224c22e0..8cbb56f2b 100644 --- a/src/SMESHGUI/SMESHGUI_StudyAPI.h +++ b/src/SMESHGUI/SMESHGUI_StudyAPI.h @@ -37,6 +37,7 @@ #include CORBA_SERVER_HEADER(GEOM_Shape) #include CORBA_SERVER_HEADER(SALOMEDS) #include CORBA_SERVER_HEADER(SALOMEDS_Attributes) +#include CORBA_SERVER_HEADER(SALOME_GenericObj) class SMESH_subMesh_ptr; @@ -62,7 +63,7 @@ class SMESHGUI_StudyAPI { SALOMEDS::SObject_ptr AddSubMeshOnShape (SALOMEDS::SObject_ptr SO_Mesh, SALOMEDS::SObject_ptr SO_GeomShape, SMESH::SMESH_subMesh_ptr SM, GEOM::shape_type ST); - void Update(SMESH::SMESH_Gen_ptr Gen); + void Update(SALOMEDS::Study_ptr aStudy); void ModifiedMesh( SALOMEDS::SObject_ptr MorSM, bool right); @@ -84,23 +85,14 @@ class SMESHGUI_StudyAPI { SALOMEDS::SObject_ptr GetMeshOrSubmesh (SALOMEDS::SObject_ptr SO); - SALOMEDS::SObject_ptr FindMesh (SMESH::SMESH_Mesh_ptr M); + SALOMEDS::SObject_ptr FindObject(CORBA::Object_ptr theObject); - SALOMEDS::SObject_ptr FindHypothesisOrAlgorithms (SMESH::SMESH_Hypothesis_ptr H); - - SALOMEDS::SObject_ptr FindSubMesh (SMESH::SMESH_subMesh_ptr SM); - - //SALOMEDS::ListOfSObject_ptr FindMesh (SALOMEDS_SObject_ptr SO_GeomShape); - //SALOMEDS_SObject_ptr FindSubMesh (SALOMEDS_SObject_ptr SO_Mesh, SALOMEDS_SObject_ptr SO_GeomShape); - static void setOrb(); private: //fields SALOMEDS::Study_var myStudy; SALOMEDS::StudyBuilder_var myStudyBuilder; - SALOMEDS::SComponent_var mySComponentMesh; - }; #endif diff --git a/src/SMESHGUI/SMESHGUI_Swig.cxx b/src/SMESHGUI/SMESHGUI_Swig.cxx index db4ce870e..1ab1cea6b 100644 --- a/src/SMESHGUI/SMESHGUI_Swig.cxx +++ b/src/SMESHGUI/SMESHGUI_Swig.cxx @@ -73,6 +73,9 @@ void SMESH_Swig::Init(int studyID) Engines::Component_var comp = QAD_Application::getDesktop()->getEngine("FactoryServer", "SMESH"); SMESH::SMESH_Gen_var CompMesh = SMESH::SMESH_Gen::_narrow(comp); + Engines::Component_var comp1 = QAD_Application::getDesktop()->getEngine("FactoryServer", "GEOM"); + GEOM::GEOM_Gen_var CompGeom = GEOM::GEOM_Gen::_narrow(comp1); + QAD_ResourceMgr* resMgr = QAD_Desktop::createResourceManager(); if ( resMgr ) { QString msg; @@ -83,6 +86,9 @@ void SMESH_Swig::Init(int studyID) CORBA::Object_var obj = QAD_Application::getDesktop()->getNameService()->Resolve("/myStudyManager"); SALOMEDS::StudyManager_var myStudyMgr = SALOMEDS::StudyManager::_narrow(obj); myStudy = myStudyMgr->GetStudyByID(studyID); + + CompMesh->SetCurrentStudy( myStudy.in() ); + myStudyBuilder = myStudy->NewBuilder(); SALOMEDS::GenericAttribute_var anAttr; SALOMEDS::AttributeName_var aName; @@ -104,8 +110,7 @@ void SMESH_Swig::Init(int studyID) myStudyBuilder->DefineComponentInstance(father, CompMesh ); if (aLocked) myStudy->GetProperties()->SetLocked(true); } - - mySComponentMesh=father; + mySComponentMesh = SALOMEDS::SComponent::_narrow( father ); // Tags definition Tag_HypothesisRoot = 1; @@ -131,6 +136,12 @@ SMESH_Swig::~SMESH_Swig() const char* SMESH_Swig::AddNewMesh(const char* IOR) { MESSAGE("AddNewMesh"); + + // VSR: added temporarily - to be removed - objects are published automatically by engine + SALOMEDS::SObject_var SO = myStudy->FindObjectIOR( IOR ); + if ( !SO->_is_nil() ) + return SO->GetID(); + //Find or Create Hypothesis root SALOMEDS::GenericAttribute_var anAttr; SALOMEDS::AttributeName_var aName; @@ -139,7 +150,6 @@ const char* SMESH_Swig::AddNewMesh(const char* IOR) SALOMEDS::AttributePixMap_var aPixmap; SALOMEDS::SObject_var HypothesisRoot; - ASSERT(!mySComponentMesh->_is_nil()); if (!mySComponentMesh->FindSubObject (Tag_HypothesisRoot, HypothesisRoot)) { HypothesisRoot = myStudyBuilder->NewObjectToTag (mySComponentMesh, Tag_HypothesisRoot); anAttr = myStudyBuilder->FindOrCreateAttribute(HypothesisRoot, "AttributeName"); @@ -181,6 +191,12 @@ const char* SMESH_Swig::AddNewMesh(const char* IOR) const char* SMESH_Swig::AddNewHypothesis(const char* IOR) { MESSAGE("AddNewHypothesis"); + + // VSR: added temporarily - to be removed - objects are published automatically by engine + SALOMEDS::SObject_var SO = myStudy->FindObjectIOR( IOR ); + if ( !SO->_is_nil() ) + return SO->GetID(); + //Find or Create Hypothesis root SALOMEDS::SObject_var HypothesisRoot; SALOMEDS::GenericAttribute_var anAttr; @@ -225,6 +241,12 @@ const char* SMESH_Swig::AddNewHypothesis(const char* IOR) const char* SMESH_Swig::AddNewAlgorithms(const char* IOR) { MESSAGE("AddNewAlgorithms"); + + // VSR: added temporarily - to be removed - objects are published automatically by engine + SALOMEDS::SObject_var SO = myStudy->FindObjectIOR( IOR ); + if ( !SO->_is_nil() ) + return SO->GetID(); + //Find or Create Algorithms root SALOMEDS::SObject_var AlgorithmsRoot; SALOMEDS::GenericAttribute_var anAttr; diff --git a/src/SMESHGUI/SMESHGUI_TransparencyDlg.cxx b/src/SMESHGUI/SMESHGUI_TransparencyDlg.cxx index 0ab482433..f42405abc 100644 --- a/src/SMESHGUI/SMESHGUI_TransparencyDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_TransparencyDlg.cxx @@ -31,21 +31,44 @@ using namespace std; #include "SMESHGUI.h" // QT Includes -#include #include #include #include #include -#include -#include -#include -#include #include #include "VTKViewer_ViewFrame.h" #include "VTKViewer_RenderWindowInteractor.h" #include "QAD_RightFrame.h" +#include "QAD_WaitCursor.h" #include "SALOME_ListIteratorOfListIO.hxx" +#include "SMESH_Actor.h" +#include "SALOME_Selection.h" +#include "SALOME_InteractiveObject.hxx" + +static SMESH_Actor* FindActorByEntry(const char* theEntry) +{ + QAD_Study* aStudy = SMESHGUI::GetSMESHGUI()->GetActiveStudy(); + QAD_StudyFrame *aStudyFrame = aStudy->getActiveStudyFrame(); + VTKViewer_ViewFrame* aViewFrame = dynamic_cast( aStudyFrame->getRightFrame()->getViewFrame() ); + + if(aViewFrame){ + vtkRenderer *aRenderer = aViewFrame->getRenderer(); + vtkActorCollection *aCollection = aRenderer->GetActors(); + aCollection->InitTraversal(); + while(vtkActor *anAct = aCollection->GetNextActor()){ + if(SMESH_Actor *anActor = dynamic_cast(anAct)){ + if(anActor->hasIO()){ + Handle(SALOME_InteractiveObject) anIO = anActor->getIO(); + if(anIO->hasEntry() && strcmp(anIO->getEntry(),theEntry) == 0){ + return anActor; + } + } + } + } + } + return NULL; +} //================================================================================= // class : SMESHGUI_TransparencyDlg() @@ -54,38 +77,18 @@ using namespace std; //================================================================================= SMESHGUI_TransparencyDlg::SMESHGUI_TransparencyDlg( QWidget* parent, const char* name, - SALOME_Selection* Sel, bool modal, WFlags fl ) - : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ) + : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose ) { if ( !name ) setName( "SMESHGUI_TransparencyDlg" ); - resize( 152, 107 ); setCaption( tr( "SMESH_TRANSPARENCY_TITLE" ) ); setSizeGripEnabled( TRUE ); - SMESHGUI_TransparencyDlgLayout = new QGridLayout( this ); + QGridLayout* SMESHGUI_TransparencyDlgLayout = new QGridLayout( this ); SMESHGUI_TransparencyDlgLayout->setSpacing( 6 ); SMESHGUI_TransparencyDlgLayout->setMargin( 11 ); - /*************************************************************************/ - QGroupBox* GroupButtons = new QGroupBox( this, "GroupButtons" ); - GroupButtons->setColumnLayout(0, Qt::Vertical ); - GroupButtons->layout()->setSpacing( 0 ); - GroupButtons->layout()->setMargin( 0 ); - QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() ); - GroupButtonsLayout->setAlignment( Qt::AlignTop ); - GroupButtonsLayout->setSpacing( 6 ); - GroupButtonsLayout->setMargin( 11 ); - - buttonOk = new QPushButton( GroupButtons, "buttonOk" ); - buttonOk->setText( tr( "GEOM_BUT_OK" ) ); - buttonOk->setAutoDefault( TRUE ); - buttonOk->setDefault( TRUE ); - GroupButtonsLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 0 ); - GroupButtonsLayout->addWidget( buttonOk, 0, 1 ); - GroupButtonsLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 2 ); - /*************************************************************************/ QGroupBox* GroupC1 = new QGroupBox( this, "GroupC1" ); GroupC1->setColumnLayout(0, Qt::Vertical ); @@ -96,59 +99,82 @@ SMESHGUI_TransparencyDlg::SMESHGUI_TransparencyDlg( QWidget* parent, GroupC1Layout->setSpacing( 6 ); GroupC1Layout->setMargin( 11 ); - TextLabelOpaque = new QLabel( GroupC1, "TextLabelOpaque" ); - TextLabelOpaque->setText( tr( "SMESH_TRANSPARENCY_OPAQUE" ) ); - TextLabelOpaque->setAlignment( int( QLabel::AlignLeft ) ); - GroupC1Layout->addWidget( TextLabelOpaque, 0, 0 ); - GroupC1Layout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 1 ); - TextLabelTransparent = new QLabel( GroupC1, "TextLabelTransparent" ); TextLabelTransparent->setText( tr( "SMESH_TRANSPARENCY_TRANSPARENT" ) ); - TextLabelTransparent->setAlignment( int( QLabel::AlignRight ) ); - GroupC1Layout->addWidget( TextLabelTransparent, 0, 2 ); + TextLabelTransparent->setAlignment( AlignLeft ); + GroupC1Layout->addWidget( TextLabelTransparent, 0, 0 ); + + ValueLab = new QLabel( GroupC1, "ValueLab" ); + ValueLab->setAlignment( AlignCenter ); + ValueLab->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); + QFont fnt = ValueLab->font(); fnt.setBold( true ); ValueLab->setFont( fnt ); + GroupC1Layout->addWidget( ValueLab, 0, 1 ); + + TextLabelOpaque = new QLabel( GroupC1, "TextLabelOpaque" ); + TextLabelOpaque->setText( tr( "SMESH_TRANSPARENCY_OPAQUE" ) ); + TextLabelOpaque->setAlignment( AlignRight ); + GroupC1Layout->addWidget( TextLabelOpaque, 0, 2 ); Slider1 = new QSlider( 0, 10, 1, 5, Horizontal, GroupC1, "Slider1" ); + Slider1->setFocusPolicy( QWidget::NoFocus ); Slider1->setMinimumSize( 300, 0 ); - Slider1->setTickmarks( QSlider::Left ); + Slider1->setTickmarks( QSlider::Above ); + Slider1->setTickInterval( 10 ); + Slider1->setTracking( true ); + Slider1->setMinValue( 0 ) ; + Slider1->setMaxValue( 100 ); + Slider1->setLineStep( 1 ); + Slider1->setPageStep( 10 ); GroupC1Layout->addMultiCellWidget( Slider1, 1, 1, 0, 2 ); + /*************************************************************************/ + QGroupBox* GroupButtons = new QGroupBox( this, "GroupButtons" ); + GroupButtons->setColumnLayout(0, Qt::Vertical ); + GroupButtons->layout()->setSpacing( 0 ); + GroupButtons->layout()->setMargin( 0 ); + QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() ); + GroupButtonsLayout->setAlignment( Qt::AlignTop ); + GroupButtonsLayout->setSpacing( 6 ); + GroupButtonsLayout->setMargin( 11 ); + + buttonOk = new QPushButton( GroupButtons, "buttonOk" ); + buttonOk->setText( tr( "SMESH_BUT_CLOSE" ) ); + buttonOk->setAutoDefault( TRUE ); + buttonOk->setDefault( TRUE ); + GroupButtonsLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 0 ); + GroupButtonsLayout->addWidget( buttonOk, 0, 1 ); + GroupButtonsLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 2 ); + SMESHGUI_TransparencyDlgLayout->addWidget( GroupC1, 0, 0 ); SMESHGUI_TransparencyDlgLayout->addWidget( GroupButtons, 1, 0 ); - /* Initialisations */ - this->mySMESHGUI = SMESHGUI::GetSMESHGUI() ; - this->mySel = Sel ; - - /* First call valueChanged() method for initialisation */ - /* The default value of transparency will change with the selection */ - this->myFirstInit = true ; -// Slider1->setMaxValue( 10 ); -// Slider1->setValue( 5 ) ; + mySelection = SALOME_Selection::Selection( SMESHGUI::GetSMESHGUI()->GetActiveStudy()->getSelection()); - - this->ValueHasChanged( Slider1->value() ) ; + // Initial state + this->onSelectionChanged() ; // signals and slots connections : after ValueHasChanged() connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) ); - connect( Slider1, SIGNAL( valueChanged(int) ), this, SLOT( ValueHasChanged(int) ) ); + connect( Slider1, SIGNAL( valueChanged(int) ), this, SLOT( SetTransparency() ) ); + connect( Slider1, SIGNAL( sliderMoved(int) ), this, SLOT( ValueHasChanged() ) ); + connect( SMESHGUI::GetSMESHGUI(), SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( ClickOnOk() ) ) ; + connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( onSelectionChanged() ) ); /* Move widget on the botton right corner of main widget */ int x, y ; - mySMESHGUI->DefineDlgPosition( this, x, y ) ; + SMESHGUI::GetSMESHGUI()->DefineDlgPosition( this, x, y ) ; this->move( x, y ) ; - this->show() ; /* Displays this Dialog */ + this->show(); } - - //================================================================================= // function : ~SMESHGUI_TransparencyDlg() // purpose : //================================================================================= SMESHGUI_TransparencyDlg::~SMESHGUI_TransparencyDlg() { - // no need to delete child widgets, Qt does it all for us + // no need to delete child widgets, Qt does it all for us } @@ -158,51 +184,79 @@ SMESHGUI_TransparencyDlg::~SMESHGUI_TransparencyDlg() //======================================================================= void SMESHGUI_TransparencyDlg::ClickOnOk() { - accept() ; - return ; + close(); } -//======================================================================= -// function : ClickOnClose() -// purpose : -//======================================================================= -void SMESHGUI_TransparencyDlg::ClickOnClose() +//================================================================================= +// function : SetTransparency() +// purpose : Called when value of slider change +// : or the first time as initilisation +//================================================================================= +void SMESHGUI_TransparencyDlg::SetTransparency() { - accept() ; - return ; + if ( SMESHGUI::GetSMESHGUI()->GetActiveStudy()->getActiveStudyFrame()->getTypeView() == VIEW_VTK ) { + QAD_WaitCursor wc; + float opacity = this->Slider1->value() / 100. ; + SALOME_ListIteratorOfListIO It( mySelection->StoredIObjects() ); + for( ;It.More(); It.Next() ) { + Handle(SALOME_InteractiveObject) IOS = It.Value(); + SMESH_Actor* anActor = FindActorByEntry(IOS->getEntry()); + if ( anActor ) + anActor->SetOpacity( opacity ); + } + SMESHGUI::GetSMESHGUI()->GetActiveStudy()->getActiveStudyFrame()->getRightFrame()->getViewFrame()->Repaint(); + } + ValueHasChanged(); } - //================================================================================= // function : ValueHasChanged() -// purpose : Called when value of slider change -// : or the first time as initilisation +// purpose : Called when user moves a slider //================================================================================= -void SMESHGUI_TransparencyDlg::ValueHasChanged( int newValue ) +void SMESHGUI_TransparencyDlg::ValueHasChanged() { + ValueLab->setText( QString::number( this->Slider1->value() ) + "%" ); +} - if ( mySMESHGUI->GetActiveStudy()->getActiveStudyFrame()->getTypeView() == VIEW_VTK ) { - VTKViewer_RenderWindowInteractor* myRenderInter= ((VTKViewer_ViewFrame*)mySMESHGUI->GetActiveStudy()->getActiveStudyFrame()->getRightFrame()->getViewFrame())->getRWInteractor(); - SALOME_ListIteratorOfListIO It( this->mySel->StoredIObjects() ); - Handle(SALOME_InteractiveObject) FirstIOS = mySel->firstIObject(); - if( !FirstIOS.IsNull() ) { - /* The first time as initialisation */ - if( this->myFirstInit ) { - this->myFirstInit = false ; - float transp = ( myRenderInter->GetTransparency(FirstIOS))*10.0 ; - this->Slider1->setValue( int(transp) ) ; - return; +//================================================================================= +// function : onSelectionChanged() +// purpose : Called when selection is changed +//================================================================================= +void SMESHGUI_TransparencyDlg::onSelectionChanged() +{ + if ( SMESHGUI::GetSMESHGUI()->GetActiveStudy()->getActiveStudyFrame()->getTypeView() == VIEW_VTK ) { + int opacity = 100; + if ( mySelection->IObjectCount() == 1 ) { + Handle(SALOME_InteractiveObject) FirstIOS = mySelection->firstIObject(); + if( !FirstIOS.IsNull() ) { + SMESH_Actor* anActor = FindActorByEntry( FirstIOS->getEntry() ); + if ( anActor ) + opacity = int( anActor->GetOpacity() * 100. + 0.5 ); } } - - QApplication::setOverrideCursor( Qt::waitCursor ); - for( ;It.More(); It.Next() ) { - Handle(SALOME_InteractiveObject) IOS = It.Value(); - myRenderInter->SetTransparency( IOS, newValue/10.0 ); + else if ( mySelection->IObjectCount() > 1 ) { + SALOME_ListIteratorOfListIO It( mySelection->StoredIObjects() ); + int setOp = -1; + for ( ; It.More(); It.Next() ) { + Handle(SALOME_InteractiveObject) IO = It.Value(); + if( !IO.IsNull() ) { + SMESH_Actor* anActor = FindActorByEntry( IO->getEntry() ); + if ( anActor ) { + int op = int( anActor->GetOpacity() * 100. + 0.5 ); + if ( setOp < 0 ) + setOp = op; + else if ( setOp != op ) { + setOp = 100; + break; + } + } + } + } + if ( setOp >= 0 ) + opacity = setOp; } - QApplication::restoreOverrideCursor(); + Slider1->setValue( opacity ) ; } - QApplication::restoreOverrideCursor(); - return ; + ValueHasChanged(); } diff --git a/src/SMESHGUI/SMESHGUI_TransparencyDlg.h b/src/SMESHGUI/SMESHGUI_TransparencyDlg.h index 215abe832..2bc7767fa 100644 --- a/src/SMESHGUI/SMESHGUI_TransparencyDlg.h +++ b/src/SMESHGUI/SMESHGUI_TransparencyDlg.h @@ -29,21 +29,13 @@ #ifndef DIALOGBOX_TRANSPARENCYDLG_H #define DIALOGBOX_TRANSPARENCYDLG_H -#include "SALOME_Selection.h" -#include "SALOME_InteractiveObject.hxx" - // QT Includes -#include #include -class QVBoxLayout; -class QHBoxLayout; -class QGridLayout; -class QFrame; class QLabel; class QPushButton; class QSlider; -class SMESHGUI; +class SALOME_Selection; //================================================================================= // class : SMESHGUI_TransparencyDlg @@ -55,34 +47,28 @@ class SMESHGUI_TransparencyDlg : public QDialog public: SMESHGUI_TransparencyDlg( QWidget* parent = 0, - const char* name = 0, - SALOME_Selection* Sel = 0, - bool modal = TRUE, - WFlags fl = 0 ); + const char* name = 0, + bool modal = false, + WFlags fl = 0 ); ~SMESHGUI_TransparencyDlg(); private : - SMESHGUI* mySMESHGUI ; /* Current GeomGUI object */ - bool myFirstInit ; /* Inform for the first init */ - SALOME_Selection* mySel; /* User selection */ - - QPushButton* buttonOk; - QLabel* TextLabelOpaque; - QLabel* TextLabelTransparent; - QSlider* Slider1; + SALOME_Selection* mySelection; + + QPushButton* buttonOk; + QLabel* TextLabelOpaque; + QLabel* ValueLab; + QLabel* TextLabelTransparent; + QSlider* Slider1; public slots: void ClickOnOk(); - void ClickOnClose(); - void ValueHasChanged( int newValue ) ; - -protected: - QGridLayout* SMESHGUI_TransparencyDlgLayout; - QHBoxLayout* Layout1; - QHBoxLayout* Layout2; + void ValueHasChanged() ; + void SetTransparency(); + void onSelectionChanged(); }; #endif // DIALOGBOX_TRANSPARENCYDLG_H diff --git a/src/SMESHGUI/SMESHGUI_XmlHandler.cxx b/src/SMESHGUI/SMESHGUI_XmlHandler.cxx new file mode 100644 index 000000000..ee42768b1 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_XmlHandler.cxx @@ -0,0 +1,187 @@ +// SMESH SMESHGUI : reading of xml file with list of available hypotheses and algorithms +// Copyright (C) 2003 CEA +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESHGUI_XmlHandler.cxx +// Author : Julia DOROVSKIKH +// Module : SMESH +// $Header$ + +using namespace std; +#define INCLUDE_MENUITEM_DEF + +#include "SMESHGUI_XmlHandler.h" + +// QT Include +//#include +#include + +/*! + Constructor +*/ +SMESHGUI_XmlHandler::SMESHGUI_XmlHandler() +{ +} + +/*! + Destructor +*/ +SMESHGUI_XmlHandler::~SMESHGUI_XmlHandler() +{ +} + +/*! + Starts parsing of document. Does some initialization + + Reimplemented from QXmlDefaultHandler. +*/ +bool SMESHGUI_XmlHandler::startDocument() +{ + myErrorProt = ""; + return TRUE; +} + +/*! + Does different actions depending on the name of the tag and the + state you are in document. + + Reimplemented from QXmlDefaultHandler. +*/ +bool SMESHGUI_XmlHandler::startElement (const QString&, const QString&, + const QString& qName, + const QXmlAttributes& atts) +{ + if (qName == "meshers") + { + myHypothesesMap.clear(); + myAlgorithmsMap.clear(); + } + else if (qName == "meshers-group") // group of hypotheses and algorithms + { +// if (atts.value("server-lib") != "") + { + myPluginName = atts.value("name"); + myServerLib = atts.value("server-lib"); + myClientLib = atts.value("gui-lib"); + + QString aResName = atts.value("resources"); + if (aResName != "") + { + MESSAGE("Loading Resources " << aResName); + QAD_ResourceMgr* resMgr = QAD_Desktop::createResourceManager(); + QString msg; + if (!resMgr->loadResources(aResName, msg)) + MESSAGE(msg); + } + } + } + else if (qName == "hypotheses") // group of hypotheses + { + } + else if (qName == "algorithms") // group of algorithms + { + } + else if (qName == "hypothesis" || qName == "algorithm") // hypothesis or algorithm + { + if (atts.value("type") != "") + { + QString aHypAlType = atts.value("type"); + QString aLabel = atts.value("label-id"); + QString anIcon = atts.value("icon-id"); + HypothesisData* aHypLibNames = + new HypothesisData (myPluginName, myServerLib, myClientLib, + aLabel, anIcon); + + if (qName == "algorithm") + { + myAlgorithmsMap[(char*)aHypAlType.latin1()] = aHypLibNames; + } + else + { + myHypothesesMap[(char*)aHypAlType.latin1()] = aHypLibNames; + } + } + } + else + { + // error + return FALSE; + } + return TRUE; +} + + +/*! + Reimplemented from QXmlDefaultHandler. +*/ +bool SMESHGUI_XmlHandler::endElement (const QString&, const QString&, const QString&) +{ + return TRUE; +} + + +/*! + Reimplemented from QXmlDefaultHandler. +*/ +bool SMESHGUI_XmlHandler::characters (const QString& ch) +{ + // we are not interested in whitespaces + QString ch_simplified = ch.simplifyWhiteSpace(); + if ( ch_simplified.isEmpty() ) + return TRUE; + return TRUE; +} + + +/*! + Returns the default error string. + + Reimplemented from QXmlDefaultHandler. +*/ +QString SMESHGUI_XmlHandler::errorString() +{ + return "the document is not in the quote file format"; +} + +/*! + Returns the error protocol if parsing failed + + Reimplemented from QXmlDefaultHandler. +*/ +QString SMESHGUI_XmlHandler::errorProtocol() +{ + return myErrorProt; +} + +/*! + Returns exception + + Reimplemented from QXmlDefaultHandler. +*/ +bool SMESHGUI_XmlHandler::fatalError (const QXmlParseException& exception) +{ + myErrorProt += QString("fatal parsing error: %1 in line %2, column %3\n") + .arg(exception.message()) + .arg(exception.lineNumber()) + .arg(exception.columnNumber()); + + return QXmlDefaultHandler::fatalError( exception ); +} diff --git a/src/SMESHGUI/SMESHGUI_XmlHandler.h b/src/SMESHGUI/SMESHGUI_XmlHandler.h new file mode 100644 index 000000000..363d9830c --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_XmlHandler.h @@ -0,0 +1,58 @@ +// SMESH SMESHGUI : reading of xml file with list of available hypotheses and algorithms +// +// Copyright (C) 2003 CEA +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESHGUI_XmlHandler.cxx +// Author : Julia DOROVSKIKH +// Module : SMESH +// $Header$ + +#include "SMESHGUI.h" + +#include +#include + +class SMESHGUI_XmlHandler : public QXmlDefaultHandler +{ + public: + SMESHGUI_XmlHandler(); + virtual ~SMESHGUI_XmlHandler(); + + bool startDocument(); + bool startElement( const QString& namespaceURI, const QString& localName, + const QString& qName, const QXmlAttributes& atts ); + bool endElement( const QString& namespaceURI, const QString& localName, const QString& qName ); + bool characters( const QString& ch ); + + QString errorString(); + QString errorProtocol(); + bool fatalError (const QXmlParseException& exception); + + public: + map myHypothesesMap; + map myAlgorithmsMap; + + private: + QString myErrorProt; + QString myPluginName; + QString myServerLib; + QString myClientLib; +}; diff --git a/src/SMESHGUI/SMESH_icons.po b/src/SMESHGUI/SMESH_icons.po index 60f92f2d7..741477620 100644 --- a/src/SMESHGUI/SMESH_icons.po +++ b/src/SMESHGUI/SMESH_icons.po @@ -59,22 +59,6 @@ msgstr "mesh_connectivity.png" # Hypothesis #----------------------------------------------------------- -#Hypo Local Length -msgid "ICON_DLG_LOCAL_LENGTH" -msgstr "mesh_hypo_length.png" - -#Hypo Nb Segments -msgid "ICON_DLG_NB_SEGMENTS" -msgstr "mesh_hypo_segment.png" - -#Hypo Max Area -msgid "ICON_DLG_MAX_ELEMENT_AREA" -msgstr "mesh_hypo_area.png" - -#Hypo Max Volume -msgid "ICON_DLG_MAX_ELEMENT_VOLUME" -msgstr "mesh_hypo_volume.png" - #Set Algo msgid "ICON_DLG_ADD_ALGORITHM" msgstr "mesh_set_algo.png" @@ -118,53 +102,40 @@ msgstr "mesh_hexa.png" #----------------------------------------------------------- -# ObjectBrother +# ObjectBrowser #----------------------------------------------------------- #mesh_tree_mesh msgid "ICON_SMESH_TREE_MESH" msgstr "mesh_tree_mesh.png" +#mesh_tree_group +msgid "ICON_SMESH_TREE_GROUP" +msgstr "mesh_tree_group.png" + #mesh_tree_algo msgid "ICON_SMESH_TREE_ALGO" msgstr "mesh_tree_algo.png" -#mesh_tree_algo_regular -msgid "ICON_SMESH_TREE_ALGO_Regular_1D" -msgstr "mesh_tree_algo_regular.png" - -#mesh_tree_algo_hexa -msgid "ICON_SMESH_TREE_ALGO_Hexa_3D" -msgstr "mesh_tree_algo_hexa.png" - -#mesh_tree_algo_mefisto -msgid "ICON_SMESH_TREE_ALGO_MEFISTO_2D" -msgstr "mesh_tree_algo_mefisto.png" - -#mesh_tree_algo_quad -msgid "ICON_SMESH_TREE_ALGO_Quadrangle_2D" -msgstr "mesh_tree_algo_quad.png" - #mesh_tree_hypo msgid "ICON_SMESH_TREE_HYPO" msgstr "mesh_tree_hypo.png" -#mesh_tree_hypo_area -msgid "ICON_SMESH_TREE_HYPO_MaxElementArea" -msgstr "mesh_tree_hypo_area.png" +#mesh_tree_mesh_warn +msgid "ICON_SMESH_TREE_MESH_WARN" +msgstr "mesh_tree_mesh_warn.png" -#mesh_tree_hypo_length -msgid "ICON_SMESH_TREE_HYPO_LocalLength" -msgstr "mesh_tree_hypo_length.png" +#mesh_tree_mesh +msgid "ICON_SMESH_TREE_MESH_IMPORTED" +msgstr "mesh_tree_importedmesh.png" -#mesh_tree_hypo_segment -msgid "ICON_SMESH_TREE_HYPO_NumberOfSegments" -msgstr "mesh_tree_hypo_segment.png" -#mesh_tree_hypo_volume -msgid "ICON_SMESH_TREE_HYPO_MaxElementVolume" -msgstr "mesh_tree_hypo_volume.png" +#----------------------------------------------------------- +# Group +#----------------------------------------------------------- -#mesh_tree_mesh_warn -msgid "ICON_SMESH_TREE_MESH_WARN" -msgstr "mesh_tree_mesh_warn.png" +msgid "ICON_EDIT_GROUP" +msgstr "mesh_edit_group.png" + +msgid "ICON_CONSTRUCT_GROUP" +msgstr "mesh_make_group.png" diff --git a/src/SMESHGUI/SMESH_msg_en.po b/src/SMESHGUI/SMESH_msg_en.po index c593f9571..38d6f37ed 100644 --- a/src/SMESHGUI/SMESH_msg_en.po +++ b/src/SMESHGUI/SMESH_msg_en.po @@ -38,11 +38,34 @@ msgstr "&No" msgid "SMESH_BUT_CANCEL" msgstr "&Cancel" +#Add +msgid "SMESH_BUT_ADD" +msgstr "A&dd" + +#Remove +msgid "SMESH_BUT_REMOVE" +msgstr "&Remove" + +#Set Filters +msgid "SMESH_BUT_FILTER" +msgstr "Set &Filters" + +#Sort +msgid "SMESH_BUT_SORT" +msgstr "&Sort List" + +#Create +msgid "SMESH_BUT_CREATE" +msgstr "Create" #------------------------------------------------------------------------- # WARNING #------------------------------------------------------------------------- +#Error +msgid "SMESH_ERROR" +msgstr "Error" + #Warning msgid "SMESH_WRN_WARNING" msgstr "Warning" @@ -83,6 +106,9 @@ msgstr "Activate Nodes Selection Mode" msgid "SMESH_WRN_SELECTIONMODE_DIAGONAL" msgstr "Activate Link Selection Mode" +#Empty name +msgid "SMESH_WRN_EMPTY_NAME" +msgstr "Empty name is not valid" #------------------------------------------------------------------------- # MEN @@ -114,19 +140,19 @@ msgstr "SubMeshes On Compound" #Applied Algorithm msgid "SMESH_MEN_APPLIED_ALGORIHTMS" -msgstr "Applied Algorithm" +msgstr "Applied Algorithms" #Applied Hypothesis msgid "SMESH_MEN_APPLIED_HYPOTHESIS" -msgstr "Applied Hypothesis" +msgstr "Applied Hypotheses" #Hypothesis Definition msgid "SMESH_MEN_HYPOTHESIS" -msgstr "Hypothesis Definition" +msgstr "Hypotheses" #Algorithms Definition msgid "SMESH_MEN_ALGORITHMS" -msgstr "Algorithms Definition" +msgstr "Algorithms" #------------------------------------------------------------------------- @@ -207,6 +233,18 @@ msgstr "SubMesh" # -------------- Hypothesis / Algorithm -------------- +#Meshers file +msgid "MESHERS_FILE_NO_VARIABLE" +msgstr "Environment variable SMESH_MeshersList is not defined" + +#Meshers file +msgid "MESHERS_FILE_CANT_OPEN" +msgstr "Can not open resource file" + +#Meshers file +msgid "MESHERS_FILE_CHECK_VARIABLE" +msgstr "Check environment variable SMESH_MeshersList" + #Hypothesis msgid "SMESH_ADD_HYPOTHESIS" msgstr "Hypothesis" @@ -219,14 +257,6 @@ msgstr "Hypothesis Assignation" msgid "SMESH_OBJECT_HYPOTHESIS" msgstr "Hypothesis" -#Local Length -msgid "SMESH_LOCAL_LENGTH_HYPOTHESIS" -msgstr "Local Length" - -#Hypothesis Construction -msgid "SMESH_LOCAL_LENGTH_TITLE" -msgstr "Hypothesis Construction" - #Algorithms msgid "SMESH_ADD_ALGORITHM" msgstr "Algorithms" @@ -239,38 +269,6 @@ msgstr "Algorithms Assignation" msgid "SMESH_OBJECT_ALGORITHM" msgstr "Algorithm" -#Number of Segments -msgid "SMESH_NB_SEGMENTS_HYPOTHESIS" -msgstr "Number of Segments" - -#Hypothesis Construction -msgid "SMESH_NB_SEGMENTS_TITLE" -msgstr "Hypothesis Construction" - -#Max. Area -msgid "SMESH_MAX_ELEMENT_AREA" -msgstr "Max. Area" - -#Max. Element Area -msgid "SMESH_MAX_ELEMENT_AREA_HYPOTHESIS" -msgstr "Max. Element Area" - -#Hypothesis Construction -msgid "SMESH_MAX_ELEMENT_AREA_TITLE" -msgstr "Hypothesis Construction" - -#Max. Volume -msgid "SMESH_MAX_ELEMENT_VOLUME" -msgstr "Max. Volume" - -#Max. Element Volume -msgid "SMESH_MAX_ELEMENT_VOLUME_HYPOTHESIS" -msgstr "Max. Element Volume" - -#Hypothesis Construction -msgid "SMESH_MAX_ELEMENT_VOLUME_TITLE" -msgstr "Hypothesis Construction" - # -------------- Nodes / Segments / Elements -------------- @@ -391,87 +389,118 @@ msgstr "Add Hexahedron" #Opacity msgid "SMESH_TRANSPARENCY_OPAQUE" -msgstr "Opacity" +msgstr "---> Opaque" #Transparency msgid "SMESH_TRANSPARENCY_TITLE" -msgstr "Transparency" +msgstr "Change Transparency" #Fully Transparency msgid "SMESH_TRANSPARENCY_TRANSPARENT" -msgstr "Fully Transparency" +msgstr "Transparent <---" # -------------- Preferences ----------- +#Scalar Bar Preferences +msgid "SMESH_PROPERTIES_SCALARBAR" +msgstr "Scalar Bar Properties" + +#Scalar Bar Properties +msgid "SMESH_PREFERENCES_SCALARBAR" +msgstr "Scalar Bar Preferences" + +#Scalar Bar Range +msgid "SMESH_RANGE_SCALARBAR" +msgstr "Scalar Range" + +#Scalar Bar Range Min Value +msgid "SMESH_RANGE_MIN" +msgstr "Min value:" + +#Scalar Bar Range Max Value +msgid "SMESH_RANGE_MAX" +msgstr "Max value:" + +#Scalar Bar Font +msgid "SMESH_FONT_SCALARBAR" +msgstr "Font" + #Arial msgid "SMESH_FONT_ARIAL" msgstr "Arial" -#Bold -msgid "SMESH_FONT_BOLD" -msgstr "Bold" - #Courier msgid "SMESH_FONT_COURIER" msgstr "Courier" -#Dimensions -msgid "SMESH_DIMENSIONS" -msgstr "Dimensions" - -#Font -msgid "SMESH_FONT" -msgstr "Font" - -#Height -msgid "SMESH_HEIGHT" -msgstr "Height" +#Times +msgid "SMESH_FONT_TIMES" +msgstr "Times" -#Horizontal -msgid "SMESH_HORIZONTAL" -msgstr "Horizontal" +#Bold +msgid "SMESH_FONT_BOLD" +msgstr "Bold" #Italic msgid "SMESH_FONT_ITALIC" msgstr "Italic" -#Scalar Bar Preferences -msgid "SMESH_PREFERENCES_SCALARBAR" -msgstr "Scalar Bar Preferences" +#Shadow +msgid "SMESH_FONT_SHADOW" +msgstr "Shadow" + +#Title +msgid "SMESH_TITLE" +msgstr "Title:" + +#Labels +msgid "SMESH_LABELS" +msgstr "Labels:" + +#Colors & Labels +msgid "SMESH_LABELS_COLORS_SCALARBAR" +msgstr "Colors && Labels" #Number Of Colors msgid "SMESH_NUMBEROFCOLORS" -msgstr "Number Of Colors" +msgstr "Nb of colors:" #Number Of Labels msgid "SMESH_NUMBEROFLABELS" -msgstr "Number Of Labels" +msgstr "Nb of labels:" #Orientation msgid "SMESH_ORIENTATION" msgstr "Orientation" -#Properties -msgid "SMESH_PROPERTIES" -msgstr "Properties" - -#Shadow -msgid "SMESH_FONT_SHADOW" -msgstr "Shadow" - -#Times -msgid "SMESH_FONT_TIMES" -msgstr "Times" - #Vertical msgid "SMESH_VERTICAL" msgstr "Vertical" +#Horizontal +msgid "SMESH_HORIZONTAL" +msgstr "Horizontal" + +#Position & Size +msgid "SMESH_POSITION_SIZE_SCALARBAR" +msgstr "Origin && Size" + +#X +msgid "SMESH_X_SCALARBAR" +msgstr "X:" + +#Y +msgid "SMESH_Y_SCALARBAR" +msgstr "Y:" + #Width msgid "SMESH_WIDTH" -msgstr "Width" +msgstr "Width:" +#Height +msgid "SMESH_HEIGHT" +msgstr "Height:" # -------------- ScalarBar -------------- @@ -485,7 +514,7 @@ msgstr "Min" #ScalarBar msgid "SMESH_SCALARBAR" -msgstr "ScalarBar" +msgstr "Scalar Bar" #Update View msgid "SMESH_UPDATEVIEW" @@ -510,10 +539,6 @@ msgstr "Manifold Edges" msgid "SMESH_NONMANIFOLDEDGES" msgstr "Non Manifold Edges" -#Edges Connectivity -msgid "SMESH_EDGES_CONNECTIVITY" -msgstr "Edges Connectivity" - #Edges Connectivity msgid "SMESH_EDGES_CONNECTIVITY_TITLE" msgstr "Edges Connectivity" @@ -551,72 +576,87 @@ msgstr "Diagonal Inversion" msgid "SMESH_MESHINFO_TITLE" msgstr "Mesh Infos" -#Number Of 1D Elements -msgid "SMESH_MESHINFO_NB1D" -msgstr "Number Of 1D Elements" - -#Number Of 2D Elements -msgid "SMESH_MESHINFO_NB2D" -msgstr "Number Of 2D Elements" +#Mesh Infos +msgid "SMESH_MESHINFO_NAME" +msgstr "Name" -#Number Of 3D Elements -msgid "SMESH_MESHINFO_NB3D" -msgstr "Number Of 3D Elements" +#Faces : +msgid "SMESH_MESHINFO_ELEMENTS" +msgstr "Elements" #Edges : msgid "SMESH_MESHINFO_EDGES" -msgstr "Edges :" +msgstr "Edges" #Nodes : msgid "SMESH_MESHINFO_NODES" -msgstr "Nodes :" +msgstr "Nodes" + +#Faces : +msgid "SMESH_MESHINFO_FACES" +msgstr "Faces" + +#Total : +msgid "SMESH_MESHINFO_TOTAL" +msgstr "Total" #Triangles : msgid "SMESH_MESHINFO_TRIANGLES" -msgstr "Triangles :" +msgstr "Triangles" #Quadrangles : msgid "SMESH_MESHINFO_QUADRANGLES" -msgstr "Quadrangles :" +msgstr "Quadrangles" + +#Volumes : +msgid "SMESH_MESHINFO_VOLUMES" +msgstr "Volumes" #Tetrahedrons : msgid "SMESH_MESHINFO_TETRAS" -msgstr "Tetrahedrons :" +msgstr "Tetrahedrons" #Hexahedrons : msgid "SMESH_MESHINFO_HEXAS" -msgstr "Hexahedrons :" +msgstr "Hexahedrons" +#Pyramids : +msgid "SMESH_MESHINFO_PYRAS" +msgstr "Pyramids" -# -------------- Controls -------------- +#Prisms : +msgid "SMESH_MESHINFO_PRISMS" +msgstr "Prisms" -#Length -msgid "SMESH_CONTROL_LENGTH_EDGES" -msgstr "Length" +#Type : +msgid "SMESH_MESHINFO_TYPE" +msgstr "Type" -#Area -msgid "SMESH_CONTROL_AREA_ELEMENTS" -msgstr "Area" +#Entities : +msgid "SMESH_MESHINFO_ENTITIES" +msgstr "Entities" -#Taper -msgid "SMESH_CONTROL_TAPER_ELEMENTS" -msgstr "Taper" +#All types : +msgid "SMESH_MESHINFO_ALL_TYPES" +msgstr "Heterogenous" -#Aspect Ratio -msgid "SMESH_CONTROL_ASPECTRATIO_ELEMENTS" -msgstr "Aspect Ratio" +#No valid selection : +msgid "SMESH_BAD_SELECTION" +msgstr "No valid selection" -#Minimum Angle -msgid "SMESH_CONTROL_MINIMUMANGLE_ELEMENTS" -msgstr "Minimum Angle" +# --------- Create hypotheses/algorithms --------- -#Warp -msgid "SMESH_CONTROL_WARP_ELEMENTS" -msgstr "Warp" +msgid "SMESH_CREATE_HYPOTHESES" +msgstr "Create hypotheses" -#Skew -msgid "SMESH_CONTROL_SKEW_ELEMENTS" -msgstr "Skew" +msgid "SMESH_CREATE_ALGORITHMS" +msgstr "Create algorithms" + +msgid "SMESH_AVAILABLE_ALGORITHMS" +msgstr "Available algorithms" + +msgid "SMESH_AVAILABLE_HYPOTHESES" +msgstr "Available hypotheses" # -------------- Edit -------------- @@ -636,3 +676,247 @@ msgstr "Available" msgid "SMESH_EDIT_USED" msgstr "Used" +# -------------- Group -------------- + +#Create Group +msgid "SMESH_CREATE_GROUP_TITLE" +msgstr "Create Group" + +#Edit Group +msgid "SMESH_EDIT_GROUP_TITLE" +msgstr "Edit Group" + +#Elements Type +msgid "SMESH_ELEMENTS_TYPE" +msgstr "Elements Type" + +#Face +msgid "SMESH_FACE" +msgstr "Face" + +#Volume +msgid "SMESH_VOLUME" +msgstr "Volume" + +#Content +msgid "SMESH_CONTENT" +msgstr "Content" + +#Select rom +msgid "SMESH_SELECT_FROM" +msgstr "Select From" + +#Group +msgid "SMESH_GROUP" +msgstr "Group" + +#%1 SubMeshes +msgid "SMESH_SUBMESH_SELECTED" +msgstr "%1 SubMeshes" + +#%1 Groups +msgid "SMESH_GROUP_SELECTED" +msgstr "%1 Groups" + + +# -------------- Preferences - Selection -------------- +msgid "SMESH_PREF_SELECTION" +msgstr "Preferences - Selection" + +msgid "SMESH_SELECTION" +msgstr "Selection" + +msgid "SMESH_PRESELECTION" +msgstr "Preselection" + +msgid "SMESH_HILIGHT_COLOR" +msgstr "Highlight Color" + +msgid "SMESH_ELEMENTS_COLOR" +msgstr "Mesh Element Color" + +msgid "SMESH_PRECISION" +msgstr "Precision" + +msgid "SMESH_OUTLINE_COLOR" +msgstr "Mesh Object Color" + + +# -------------- SMESHGUI_FilterDlg -------------- +msgid "SMESHGUI_FilterDlg::FACES_TLT" +msgstr "Filter for Faces" + +msgid "SMESHGUI_FilterDlg::EDGES_TLT" +msgstr "Filter for Edges" + +msgid "SMESHGUI_FilterDlg::ADD" +msgstr "Add" + +msgid "SMESHGUI_FilterDlg::REMOVE" +msgstr "Remove" + +msgid "SMESHGUI_FilterDlg::CRITERION" +msgstr "Criterion" + +msgid "SMESHGUI_FilterDlg::COMPARE" +msgstr "Compare" + +msgid "SMESHGUI_FilterDlg::THRESHOLD_VALUE" +msgstr "Threshold value" + +msgid "SMESHGUI_FilterDlg::UNARY" +msgstr "Unary" + +msgid "SMESHGUI_FilterDlg::BINARY" +msgstr "Binary" + +msgid "SMESHGUI_FilterDlg::FREE_BORDERS" +msgstr "Free borders" + +msgid "SMESHGUI_FilterDlg::MULTI_BORDERS" +msgstr "Borders at multi-connections" + +msgid "SMESHGUI_FilterDlg::LENGTH" +msgstr "Length" + +msgid "SMESHGUI_FilterDlg::ASPECT_RATIO" +msgstr "Aspect ratio" + +msgid "SMESHGUI_FilterDlg::WARPING" +msgstr "Warping" + +msgid "SMESHGUI_FilterDlg::MINIMUM_ANGLE" +msgstr "Minimum angle" + +msgid "SMESHGUI_FilterDlg::TAPER" +msgstr "Taper" + +msgid "SMESHGUI_FilterDlg::SKEW" +msgstr "Skew" + +msgid "SMESHGUI_FilterDlg::AREA" +msgstr "Area" + +msgid "SMESHGUI_FilterDlg::LESS_THAN" +msgstr "Less than" + +msgid "SMESHGUI_FilterDlg::MORE_THAN" +msgstr "More than" + +msgid "SMESHGUI_FilterDlg::EQUAL_TO" +msgstr "Equal to" + +msgid "SMESHGUI_FilterDlg::NOT" +msgstr "Not" + +msgid "SMESHGUI_FilterDlg::AND" +msgstr "And" + +msgid "SMESHGUI_FilterDlg::OR" +msgstr "Or" + +msgid "SMESHGUI_FilterDlg::ERROR" +msgstr "Threshold value is not correctly specified\nPlease enter correct value and try again" + +msgid "SMESHGUI_FilterDlg::MULTIEDGES_ERROR" +msgstr "Threshold value of borders at multi-connections can not be equal 1\nPlease enter correct value and try again" + +msgid "SMESHGUI_FilterDlg::SOURCE" +msgstr "Source" + +msgid "SMESHGUI_FilterDlg::MESH" +msgstr "Mesh" + +msgid "SMESHGUI_FilterDlg::SELECTION" +msgstr "Current Selection" + +msgid "SMESHGUI_FilterDlg::CURRENT_GROUP" +msgstr "Current Group" + +msgid "SMESHGUI_FilterDlg::NONE" +msgstr "None" + +msgid "SMESHGUI_FilterDlg::SET_IN_VIEWER" +msgstr "Insert filter in viewer" + +msgid "SMESHGUI_FilterDlg::CLEAR" +msgstr "Clear" + +# -------------- SMESHGUI -------------- +msgid "SMESHGUI::MESH_IS_NOT_SELECTED" +msgstr "There is no selected mesh\nPlease, select a mesh and try again" + +msgid "SMESHGUI::NOT_A_VTK_VIEWER" +msgstr "This command is available in VTK viewer only\nPlease, create VTK viewer and try again" + +msgid "SMESHGUI::LENGTH_EDGES" +msgstr "Length" + +msgid "SMESHGUI::FREE_BORDERS" +msgstr "Free borders" + +msgid "SMESHGUI::MULTI_BORDERS" +msgstr "Borders at multi-connections" + +msgid "SMESHGUI::AREA_ELEMENTS" +msgstr "Area" + +msgid "SMESHGUI::TAPER_ELEMENTS" +msgstr "Taper" + +msgid "SMESHGUI::ASPECTRATIO_ELEMENTS" +msgstr "Aspect Ratio" + +msgid "SMESHGUI::MINIMUMANGLE_ELEMENTS" +msgstr "Minimum Angle" + +msgid "SMESHGUI::WARP_ELEMENTS" +msgstr "Warp" + +msgid "SMESHGUI::SKEW_ELEMENTS" +msgstr "Skew" + +msgid "SMESH_INSUFFICIENT_DATA" +msgstr "Insufficient input value" + +msgid "SMESH_HYP_1" +msgstr "Algorithm misses a hypothesis" + +msgid "SMESH_HYP_2" +msgstr "Concurrent hypotheses on a shape" + +msgid "SMESH_HYP_3" +msgstr "Hypothesis has a bad parameter value" + +msgid "SMESH_HYP_4" +msgstr "Unknown fatal error while assigning hypothesis" + +msgid "SMESH_HYP_5" +msgstr "Hypothesis is not suitable in the current context" + +msgid "SMESH_HYP_6" +msgstr "Non-conform mesh is produced using applied hypotheses" + +msgid "SMESH_HYP_7" +msgstr "Such hypothesis is already assigned to the shape" + +msgid "SMESH_HYP_8" +msgstr "Hypothesis and submesh dimensions mismatch" + +msgid "SMESH_DRS_1" +msgstr "MED file contains no mesh with the given name" + +msgid "SMESH_DRS_2" +msgstr "" +"MED file has overlapped ranges of element numbers,\n" +" the numbers from the file are ignored" + +msgid "SMESH_DRS_3" +msgstr "Some elements were skipped due to incorrect file data" + +msgid "SMESH_DRS_4" +msgstr " The file is incorrect,\n" + "some information will be missed" + +msgid "INF_SELECT_OBJECT" +msgstr "Select an object" \ No newline at end of file diff --git a/src/SMESH_I/Makefile.in b/src/SMESH_I/Makefile.in index 44991ebde..2f38fc04e 100644 --- a/src/SMESH_I/Makefile.in +++ b/src/SMESH_I/Makefile.in @@ -30,59 +30,64 @@ top_srcdir=@top_srcdir@ top_builddir=../.. srcdir=@srcdir@ -VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl:${KERNEL_ROOT_DIR}/idl/salome:${MED_ROOT_DIR}/idl/salome +VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl: @COMMENCE@ +# header files +EXPORT_HEADERS= \ + SMESH_Gen_i.hxx \ + SMESH_Algo_i.hxx \ + SMESH_1D_Algo_i.hxx \ + SMESH_2D_Algo_i.hxx \ + SMESH_3D_Algo_i.hxx \ + SMESH_subMesh_i.hxx \ + SMESH_topo.hxx \ + SMESH_Mesh_i.hxx \ + SMESH_Hypothesis_i.hxx + EXPORT_PYSCRIPTS = smeshpy.py SMESH_test.py # Libraries targets LIB= libSMESHEngine.la -LIB_SRC = SMESH_Gen_i.cxx SMESH_Mesh_i.cxx SMESH_MEDMesh_i.cxx \ - SMESH_MEDFamily_i.cxx SMESH_MEDSupport_i.cxx \ - SMESH_subMesh_i.cxx \ - SMESH_MeshEditor_i.cxx \ - SMESH_Hypothesis_i.cxx \ - SMESH_topo.cxx SMESH_HypothesisFactory_i.cxx \ - SMESH_Algo_i.cxx \ - SMESH_1D_Algo_i.cxx \ - SMESH_2D_Algo_i.cxx \ - SMESH_3D_Algo_i.cxx \ - SMESH_NumberOfSegments_i.cxx \ - SMESH_LocalLength_i.cxx \ - SMESH_MaxElementArea_i.cxx \ - SMESH_LengthFromEdges_i.cxx \ - SMESH_MaxElementVolume_i.cxx \ - SMESH_Regular_1D_i.cxx \ - SMESH_Quadrangle_2D_i.cxx \ - SMESH_MEFISTO_2D_i.cxx \ - SMESH_Hexa_3D_i.cxx +LIB_SRC = \ + SMESH_Gen_i.cxx \ + SMESH_Mesh_i.cxx \ + SMESH_MEDMesh_i.cxx \ + SMESH_MEDFamily_i.cxx \ + SMESH_MEDSupport_i.cxx \ + SMESH_subMesh_i.cxx \ + SMESH_MeshEditor_i.cxx \ + SMESH_Hypothesis_i.cxx \ + SMESH_topo.cxx \ + SMESH_Algo_i.cxx \ + SMESH_1D_Algo_i.cxx \ + SMESH_2D_Algo_i.cxx \ + SMESH_3D_Algo_i.cxx \ + SMESH_Filter_i.cxx \ + SMESH_Group_i.cxx LIB_SERVER_IDL = SMESH_Gen.idl SMESH_Hypothesis.idl SMESH_Mesh.idl \ SALOME_Component.idl SALOME_Exception.idl \ - SMESH_BasicHypothesis.idl + SMESH_Filter.idl SMESH_Group.idl -LIB_CLIENT_IDL = SALOMEDS.idl GEOM_Gen.idl GEOM_Shape.idl MED.idl SALOMEDS_Attributes.idl +LIB_CLIENT_IDL = SALOMEDS.idl GEOM_Gen.idl GEOM_Shape.idl MED.idl SALOMEDS_Attributes.idl SALOME_GenericObj.idl # Executables targets BIN = BIN_SRC = # additionnal information to compil and link file -CPPFLAGS+= $(OCC_INCLUDES) $(MED2_INCLUDES) $(HDF5_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome -CXXFLAGS+= $(OCC_CXXFLAGS) $(MED2_INCLUDES) $(HDF5_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome +CPPFLAGS+= $(OCC_INCLUDES) $(MED2_INCLUDES) $(HDF5_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome \ + -I${GEOM_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS) +CXXFLAGS+= $(OCC_CXXFLAGS) $(MED2_INCLUDES) $(HDF5_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome \ + -I${GEOM_ROOT_DIR}/include/salome #IDLCXXFLAGS+= -Wbtp -LDFLAGS+= $(HDF5_LIBS) $(MED2_LIBS) -lSMESHimpl -lSalomeContainer -lSalomeNS -lSalomeDS -lRegistry -lSalomeHDFPersist -lOpUtil -lGEOMClient -lSMESHDS -lSMDS -lMEFISTO2D -lMeshDriverMED -lSalomeLifeCycleCORBA -L${KERNEL_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome - -ifeq (@WITHNETGEN@,yes) - LIB_SRC += SMESH_NETGEN_3D_i.cxx - LDFLAGS += -lNETGEN -endif +LDFLAGS+= $(HDF5_LIBS) $(MED2_LIBS) -lSMESHimpl -lSalomeContainer -lSalomeNS -lSalomeDS -lRegistry -lSalomeHDFPersist -lOpUtil -lGEOMClient -lSMESHDS -lSMDS -lMeshDriverMED -lSalomeLifeCycleCORBA -L${KERNEL_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome -lSalomeGenericObj @CONCLUDE@ - diff --git a/src/SMESH_I/SMESHEngine.cxx b/src/SMESH_I/SMESHEngine.cxx new file mode 100644 index 000000000..fc1bd440b --- /dev/null +++ b/src/SMESH_I/SMESHEngine.cxx @@ -0,0 +1,23 @@ +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + +int main(int argc, char** argv) +{ + return 1; +} diff --git a/src/SMESH_I/SMESH_1D_Algo_i.cxx b/src/SMESH_I/SMESH_1D_Algo_i.cxx index ae37c9435..a792ec287 100644 --- a/src/SMESH_I/SMESH_1D_Algo_i.cxx +++ b/src/SMESH_I/SMESH_1D_Algo_i.cxx @@ -26,46 +26,36 @@ // Module : SMESH // $Header$ -using namespace std; using namespace std; #include "SMESH_1D_Algo_i.hxx" -#include "SMESH_Gen.hxx" -#include "SMESH_HypothesisFactory.hxx" -#include "Utils_CorbaException.hxx" #include "utilities.h" //============================================================================= /*! - * + * SMESH_1D_Algo_i::SMESH_1D_Algo_i + * + * Constructor */ //============================================================================= -SMESH_1D_Algo_i::SMESH_1D_Algo_i() +SMESH_1D_Algo_i::SMESH_1D_Algo_i( PortableServer::POA_ptr thePOA ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + SMESH_Algo_i( thePOA ) { - MESSAGE("SMESH_1D_Algo_i::SMESH_1D_Algo_i"); + MESSAGE( "SMESH_1D_Algo_i::SMESH_1D_Algo_i" ); } //============================================================================= /*! - * + * SMESH_1D_Algo_i::~SMESH_1D_Algo_i + * + * Destructor */ //============================================================================= SMESH_1D_Algo_i::~SMESH_1D_Algo_i() { - MESSAGE("SMESH_1D_Algo_i::~SMESH_1D_Algo_i"); -} - -//============================================================================= -/*! - * - */ -//============================================================================= - -void SMESH_1D_Algo_i::SetImpl(::SMESH_1D_Algo* impl) -{ - MESSAGE("SMESH_1D_Algo_i::SetImpl"); - SMESH_Algo_i::SetImpl(impl); - _impl = impl; + MESSAGE( "SMESH_1D_Algo_i::~SMESH_1D_Algo_i" ); } diff --git a/src/SMESH_I/SMESH_1D_Algo_i.hxx b/src/SMESH_I/SMESH_1D_Algo_i.hxx index 4f619ea99..16ab9b441 100644 --- a/src/SMESH_I/SMESH_1D_Algo_i.hxx +++ b/src/SMESH_I/SMESH_1D_Algo_i.hxx @@ -34,21 +34,20 @@ #include "SMESH_Algo_i.hxx" -#include "SMESH_1D_Algo.hxx" - +// ====================================================== +// Generic 1D algorithm +// ====================================================== class SMESH_1D_Algo_i: - public POA_SMESH::SMESH_1D_Algo, - public SMESH_Algo_i + public virtual POA_SMESH::SMESH_1D_Algo, + public virtual SMESH_Algo_i { -public: - SMESH_1D_Algo_i(); - - virtual ~SMESH_1D_Algo_i(); - protected: - virtual void SetImpl(::SMESH_1D_Algo* impl); + // Constructor : placed in protected section to prohibit creation of generic class instance + SMESH_1D_Algo_i( PortableServer::POA_ptr thePOA ); - ::SMESH_1D_Algo* _impl; +public: + // Destructor + virtual ~SMESH_1D_Algo_i(); }; #endif diff --git a/src/SMESH_I/SMESH_2D_Algo_i.cxx b/src/SMESH_I/SMESH_2D_Algo_i.cxx index 4114c0d77..833be2ac9 100644 --- a/src/SMESH_I/SMESH_2D_Algo_i.cxx +++ b/src/SMESH_I/SMESH_2D_Algo_i.cxx @@ -26,46 +26,36 @@ // Module : SMESH // $Header$ -using namespace std; using namespace std; #include "SMESH_2D_Algo_i.hxx" -#include "SMESH_Gen.hxx" -#include "SMESH_HypothesisFactory.hxx" -#include "Utils_CorbaException.hxx" #include "utilities.h" //============================================================================= /*! - * + * SMESH_2D_Algo_i::SMESH_2D_Algo_i + * + * Constructor */ //============================================================================= -SMESH_2D_Algo_i::SMESH_2D_Algo_i() +SMESH_2D_Algo_i::SMESH_2D_Algo_i( PortableServer::POA_ptr thePOA ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + SMESH_Algo_i( thePOA ) { - MESSAGE("SMESH_2D_Algo_i::SMESH_2D_Algo_i"); + MESSAGE( "SMESH_2D_Algo_i::SMESH_2D_Algo_i" ); } //============================================================================= /*! - * + * SMESH_2D_Algo_i::~SMESH_2D_Algo_i + * + * Destructor */ //============================================================================= SMESH_2D_Algo_i::~SMESH_2D_Algo_i() { - MESSAGE("SMESH_2D_Algo_i::~SMESH_2D_Algo_i"); -} - -//============================================================================= -/*! - * - */ -//============================================================================= - -void SMESH_2D_Algo_i::SetImpl(::SMESH_2D_Algo* impl) -{ - MESSAGE("SMESH_2D_Algo_i::SetImpl"); - SMESH_Algo_i::SetImpl(impl); - _impl = impl; + MESSAGE( "SMESH_2D_Algo_i::~SMESH_2D_Algo_i" ); } diff --git a/src/SMESH_I/SMESH_2D_Algo_i.hxx b/src/SMESH_I/SMESH_2D_Algo_i.hxx index 3143aa431..cebda6197 100644 --- a/src/SMESH_I/SMESH_2D_Algo_i.hxx +++ b/src/SMESH_I/SMESH_2D_Algo_i.hxx @@ -34,21 +34,20 @@ #include "SMESH_Algo_i.hxx" -#include "SMESH_2D_Algo.hxx" - +// ====================================================== +// Generic 2D algorithm +// ====================================================== class SMESH_2D_Algo_i: - public POA_SMESH::SMESH_2D_Algo, - public SMESH_Algo_i + public virtual POA_SMESH::SMESH_2D_Algo, + public virtual SMESH_Algo_i { -public: - SMESH_2D_Algo_i(); - - virtual ~SMESH_2D_Algo_i(); - protected: - virtual void SetImpl(::SMESH_2D_Algo* impl); + // Constructor : placed in protected section to prohibit creation of generic class instance + SMESH_2D_Algo_i( PortableServer::POA_ptr thePOA ); - ::SMESH_2D_Algo* _impl; +public: + // Destructor + virtual ~SMESH_2D_Algo_i(); }; #endif diff --git a/src/SMESH_I/SMESH_3D_Algo_i.cxx b/src/SMESH_I/SMESH_3D_Algo_i.cxx index e28872c77..197fc4448 100644 --- a/src/SMESH_I/SMESH_3D_Algo_i.cxx +++ b/src/SMESH_I/SMESH_3D_Algo_i.cxx @@ -26,46 +26,36 @@ // Module : SMESH // $Header$ -using namespace std; using namespace std; #include "SMESH_3D_Algo_i.hxx" -#include "SMESH_Gen.hxx" -#include "SMESH_HypothesisFactory.hxx" -#include "Utils_CorbaException.hxx" #include "utilities.h" //============================================================================= /*! - * + * SMESH_3D_Algo_i::SMESH_3D_Algo_i + * + * Constructor */ //============================================================================= -SMESH_3D_Algo_i::SMESH_3D_Algo_i() +SMESH_3D_Algo_i::SMESH_3D_Algo_i( PortableServer::POA_ptr thePOA ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + SMESH_Algo_i( thePOA ) { - MESSAGE("SMESH_3D_Algo_i::SMESH_3D_Algo_i"); + MESSAGE( "SMESH_3D_Algo_i::SMESH_3D_Algo_i" ); } //============================================================================= /*! - * + * SMESH_3D_Algo_i::~SMESH_3D_Algo_i + * + * Destructor */ //============================================================================= SMESH_3D_Algo_i::~SMESH_3D_Algo_i() { - MESSAGE("SMESH_3D_Algo_i::~SMESH_3D_Algo_i"); -} - -//============================================================================= -/*! - * - */ -//============================================================================= - -void SMESH_3D_Algo_i::SetImpl(::SMESH_3D_Algo* impl) -{ - MESSAGE("SMESH_3D_Algo_i::SetImpl"); - SMESH_Algo_i::SetImpl(impl); - _impl = impl; + MESSAGE( "SMESH_3D_Algo_i::~SMESH_3D_Algo_i" ); } diff --git a/src/SMESH_I/SMESH_3D_Algo_i.hxx b/src/SMESH_I/SMESH_3D_Algo_i.hxx index aa75717a2..a45336a39 100644 --- a/src/SMESH_I/SMESH_3D_Algo_i.hxx +++ b/src/SMESH_I/SMESH_3D_Algo_i.hxx @@ -34,21 +34,20 @@ #include "SMESH_Algo_i.hxx" -class SMESH_3D_Algo; - +// ====================================================== +// Generic 3D algorithm +// ====================================================== class SMESH_3D_Algo_i: - public POA_SMESH::SMESH_3D_Algo, - public SMESH_Algo_i + public virtual POA_SMESH::SMESH_3D_Algo, + public virtual SMESH_Algo_i { -public: - SMESH_3D_Algo_i(); - - virtual ~SMESH_3D_Algo_i(); - protected: - virtual void SetImpl(::SMESH_3D_Algo* impl); + // Constructor : placed in protected section to prohibit creation of generic class instance + SMESH_3D_Algo_i( PortableServer::POA_ptr thePOA ); - ::SMESH_3D_Algo* _impl; +public: + // Destructor + virtual ~SMESH_3D_Algo_i(); }; #endif diff --git a/src/SMESH_I/SMESH_Algo_i.cxx b/src/SMESH_I/SMESH_Algo_i.cxx index d5f747bb2..17995f4b7 100644 --- a/src/SMESH_I/SMESH_Algo_i.cxx +++ b/src/SMESH_I/SMESH_Algo_i.cxx @@ -26,13 +26,10 @@ // Module : SMESH // $Header$ -using namespace std; using namespace std; #include "SMESH_Algo_i.hxx" -#include "SMESH_Gen.hxx" -#include "SMESH_HypothesisFactory.hxx" +#include "SMESH_Algo.hxx" -#include "Utils_CorbaException.hxx" #include "utilities.h" #include @@ -40,56 +37,49 @@ using namespace std; //============================================================================= /*! - * + * SMESH_Algo_i::SMESH_Algo_i + * + * Constructor */ //============================================================================= -SMESH_Algo_i::SMESH_Algo_i() +SMESH_Algo_i::SMESH_Algo_i( PortableServer::POA_ptr thePOA ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ) { - MESSAGE("SMESH_Algo_i::SMESH_Algo_i"); + MESSAGE( "SMESH_Algo_i::SMESH_Algo_i" ); } //============================================================================= /*! - * + * SMESH_Algo_i::~SMESH_Algo_i + * + * Destructor */ //============================================================================= SMESH_Algo_i::~SMESH_Algo_i() { - MESSAGE("SMESH_Algo_i::~SMESH_Algo_i"); + MESSAGE( "SMESH_Algo_i::~SMESH_Algo_i" ); } //============================================================================= /*! - * + * SMESH_Algo_i::GetCompatibleHypothesis + * + * Gets list of compatible hypotheses */ //============================================================================= SMESH::ListOfHypothesisName* SMESH_Algo_i::GetCompatibleHypothesis() { - MESSAGE("SMESH_Algo_i::GetCompatibleHypothesis"); - SMESH::ListOfHypothesisName_var listOfHypothesis - = new SMESH::ListOfHypothesisName; - const vector & hypList = _impl->GetCompatibleHypothesis(); + MESSAGE( "SMESH_Algo_i::GetCompatibleHypothesis" ); + SMESH::ListOfHypothesisName_var listOfHypothesis = new SMESH::ListOfHypothesisName; + const vector& hypList = ( ( ::SMESH_Algo* )myBaseImpl )->GetCompatibleHypothesis(); int nbHyp = hypList.size(); - listOfHypothesis->length(nbHyp); - for (int i=0; ilength( nbHyp ); + for ( int i = 0; i < nbHyp; i++ ) { + listOfHypothesis[ i ] = strdup( hypList[ i ].c_str() ); + } return listOfHypothesis._retn(); } - -//============================================================================= -/*! - * - */ -//============================================================================= - -void SMESH_Algo_i::SetImpl(::SMESH_Algo* impl) -{ - MESSAGE("SMESH_Algo_i::SetImpl"); - //SMESH_Algo_i::SetImpl(impl); - _impl = impl; -} diff --git a/src/SMESH_I/SMESH_Algo_i.hxx b/src/SMESH_I/SMESH_Algo_i.hxx index c5427f753..21630ec8a 100644 --- a/src/SMESH_I/SMESH_Algo_i.hxx +++ b/src/SMESH_I/SMESH_Algo_i.hxx @@ -34,23 +34,23 @@ #include "SMESH_Hypothesis_i.hxx" -#include "SMESH_Algo.hxx" - +// ====================================================== +// Generic algorithm +// ====================================================== class SMESH_Algo_i: - public POA_SMESH::SMESH_Algo, - public SMESH_Hypothesis_i + public virtual POA_SMESH::SMESH_Algo, + public virtual SMESH_Hypothesis_i { public: - SMESH_Algo_i(); + // Constructor : placed in protected section to prohibit creation of generic class instance + SMESH_Algo_i( PortableServer::POA_ptr thePOA ); +public: + // Destructor virtual ~SMESH_Algo_i(); - + + // Gets list of compatible hypotheses SMESH::ListOfHypothesisName* GetCompatibleHypothesis(); - -protected: - virtual void SetImpl(::SMESH_Algo* impl); - - ::SMESH_Algo* _impl; }; #endif diff --git a/src/SMESH_I/SMESH_Filter_i.cxx b/src/SMESH_I/SMESH_Filter_i.cxx new file mode 100644 index 000000000..724d602dd --- /dev/null +++ b/src/SMESH_I/SMESH_Filter_i.cxx @@ -0,0 +1,914 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_Filter_i.cxx +// Author : Alexey Petrov, OCC +// Module : SMESH + + +#include "SMESH_Filter_i.hxx" + +#include "SMDS_Iterator.hxx" +#include "SMDS_MeshElement.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDSAbs_ElementType.hxx" +#include "SMESH_Gen_i.hxx" +#include "SMESHDS_Mesh.hxx" + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + AUXILIARY METHODS +*/ + +static inline double getAngle( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 ) +{ + return gp_Vec( P1 - P2 ).Angle( gp_Vec( P3 - P2 ) ); +} + +static inline double getArea( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 ) +{ + gp_Vec aVec1( P2 - P1 ); + gp_Vec aVec2( P3 - P1 ); + return ( aVec1 ^ aVec2 ).Magnitude() * 0.5; +} + +static inline double getArea( const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3 ) +{ + return getArea( P1.XYZ(), P2.XYZ(), P3.XYZ() ); +} + +static inline double getDistance( const gp_XYZ& P1, const gp_XYZ& P2 ) +{ + double aDist = gp_Pnt( P1 ).Distance( gp_Pnt( P2 ) ); + return aDist; +} + +static int getNbMultiConnection( SMESHDS_Mesh* theMesh, const int theId ) +{ + if ( theMesh == 0 ) + return 0; + + const SMDS_MeshElement* anEdge = theMesh->FindElement( theId ); + if ( anEdge == 0 || anEdge->GetType() != SMDSAbs_Edge || anEdge->NbNodes() != 2 ) + return 0; + + TColStd_MapOfInteger aMap; + + int aResult = 0; + SMDS_ElemIteratorPtr anIter = anEdge->nodesIterator(); + if ( anIter != 0 ) + { + while( anIter->more() ) + { + const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next(); + if ( aNode == 0 ) + return 0; + SMDS_ElemIteratorPtr anElemIter = aNode->GetInverseElementIterator(); + while( anElemIter->more() ) + { + const SMDS_MeshElement* anElem = anElemIter->next(); + if ( anElem != 0 && anElem->GetType() != SMDSAbs_Edge ) + { + int anId = anElem->GetID(); + + if ( anIter->more() ) // i.e. first node + aMap.Add( anId ); + else if ( aMap.Contains( anId ) ) + aResult++; + } + } +// delete anElemIter; + } +// delete anIter; + } + + return aResult; +} + +using namespace std; +using namespace SMESH; + +/* + FUNCTORS +*/ + +/* + Class : NumericalFunctor_i + Description : Base class for numerical functors +*/ + +NumericalFunctor_i::NumericalFunctor_i() +: SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() ) +{ + myMesh = 0; + SMESH_Gen_i::GetPOA()->activate_object( this ); +} + +void NumericalFunctor_i::SetMesh( SMESH_Mesh_ptr theMesh ) +{ + SMESH_Mesh_i* anImplPtr = + dynamic_cast( SMESH_Gen_i::GetServant( theMesh ).in() ); + myMesh = anImplPtr ? anImplPtr->GetImpl().GetMeshDS() : 0; +} + +bool NumericalFunctor_i::getPoints( const int theId, + TColgp_SequenceOfXYZ& theRes ) const +{ + theRes.Clear(); + + if ( myMesh == 0 ) + return false; + + // Get nodes of the face + const SMDS_MeshElement* anElem = myMesh->FindElement( theId ); + if ( anElem == 0 || anElem->GetType() != GetType() ) + return false; + + int nbNodes = anElem->NbNodes(); + + SMDS_ElemIteratorPtr anIter = anElem->nodesIterator(); + if ( anIter != 0 ) + { + while( anIter->more() ) + { + const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next(); + if ( aNode != 0 ) + theRes.Append( gp_XYZ( aNode->X(), aNode->Y(), aNode->Z() ) ); + } + +// delete anIter; + } + + return true; +} + + +/* + Class : SMESH_MinimumAngleFunct + Description : Functor for calculation of minimum angle +*/ + +CORBA::Double MinimumAngle_i::GetValue( CORBA::Long theId ) +{ + TColgp_SequenceOfXYZ P; + if ( !getPoints( theId, P ) || P.Length() != 3 && P.Length() != 4 ) + return 0; + + double aMin; + + if ( P.Length() == 3 ) + { + double A0 = getAngle( P( 3 ), P( 1 ), P( 2 ) ); + double A1 = getAngle( P( 1 ), P( 2 ), P( 3 ) ); + double A2 = getAngle( P( 2 ), P( 3 ), P( 1 ) ); + + aMin = Min( A0, Min( A1, A2 ) ); + } + else + { + double A0 = getAngle( P( 4 ), P( 1 ), P( 2 ) ); + double A1 = getAngle( P( 1 ), P( 2 ), P( 3 ) ); + double A2 = getAngle( P( 2 ), P( 3 ), P( 4 ) ); + double A3 = getAngle( P( 3 ), P( 4 ), P( 1 ) ); + + aMin = Min( Min( A0, A1 ), Min( A2, A3 ) ); + } + + return aMin * 180 / PI; +} + +int MinimumAngle_i::GetType() const +{ + return SMDSAbs_Face; +} + +/* + Class : AspectRatio_i + Description : Functor for calculating aspect ratio +*/ + +CORBA::Double AspectRatio_i::GetValue( CORBA::Long theId ) +{ + TColgp_SequenceOfXYZ P; + if ( !getPoints( theId, P ) || P.Length() != 3 && P.Length() != 4 ) + return 0; + + int nbNodes = P.Length(); + + // Compute lengths of the sides + + double aLen[ nbNodes ]; + for ( int i = 0; i < nbNodes - 1; i++ ) + aLen[ i ] = getDistance( P( i + 1 ), P( i + 2 ) ); + aLen[ nbNodes - 1 ] = getDistance( P( 1 ), P( nbNodes ) ); + + // Compute aspect ratio + + if ( nbNodes == 3 ) + { + double aMaxLen = Max( aLen[ 0 ], Max( aLen[ 1 ], aLen[ 2 ] ) ); + double anArea = getArea( P( 1 ), P( 2 ), P( 3 ) ); + static double aCoef = sqrt( 3. ) / 4; + + return anArea != 0 ? aCoef * aMaxLen * aMaxLen / anArea : 0; + } + else + { + double aMaxLen = Max( Max( aLen[ 0 ], aLen[ 1 ] ), Max( aLen[ 2 ], aLen[ 3 ] ) ); + double aMinLen = Min( Min( aLen[ 0 ], aLen[ 1 ] ), Min( aLen[ 2 ], aLen[ 3 ] ) ); + + return aMinLen != 0 ? aMaxLen / aMinLen : 0; + } +} + +int AspectRatio_i::GetType() const +{ + return SMDSAbs_Face; +} + +/* + Class : Warping_i + Description : Functor for calculating warping +*/ + +CORBA::Double Warping_i::GetValue( CORBA::Long theId ) +{ + TColgp_SequenceOfXYZ P; + if ( !getPoints( theId, P ) || P.Length() != 4 ) + return 0; + + gp_XYZ G = ( P( 1 ) + P( 2 ) + P( 3 ) + P( 4 ) ) / 4; + + double A1 = ComputeA( P( 1 ), P( 2 ), P( 3 ), G ); + double A2 = ComputeA( P( 2 ), P( 3 ), P( 4 ), G ); + double A3 = ComputeA( P( 3 ), P( 4 ), P( 1 ), G ); + double A4 = ComputeA( P( 4 ), P( 1 ), P( 2 ), G ); + + return Max( Max( A1, A2 ), Max( A3, A4 ) ); +} + +double Warping_i::ComputeA( const gp_XYZ& thePnt1, + const gp_XYZ& thePnt2, + const gp_XYZ& thePnt3, + const gp_XYZ& theG ) const +{ + double aLen1 = gp_Pnt( thePnt1 ).Distance( gp_Pnt( thePnt2 ) ); + double aLen2 = gp_Pnt( thePnt2 ).Distance( gp_Pnt( thePnt3 ) ); + double L = Min( aLen1, aLen2 ) * 0.5; + + gp_XYZ GI = ( thePnt2 - thePnt1 ) / 2. - theG; + gp_XYZ GJ = ( thePnt3 - thePnt2 ) / 2. - theG; + gp_XYZ N = GI.Crossed( GJ ); + N.Normalize(); + + double H = gp_Vec( thePnt2 - theG ).Dot( gp_Vec( N ) ); + return asin( fabs( H / L ) ) * 180 / PI; +} + +int Warping_i::GetType() const +{ + return SMDSAbs_Face; +} + +/* + Class : Taper_i + Description : Functor for calculating taper +*/ + +CORBA::Double Taper_i::GetValue( CORBA::Long theId ) +{ + TColgp_SequenceOfXYZ P; + if ( !getPoints( theId, P ) || P.Length() != 4 ) + return 0; + + // Compute taper + double J1 = getArea( P( 4 ), P( 1 ), P( 2 ) ) / 2; + double J2 = getArea( P( 3 ), P( 1 ), P( 2 ) ) / 2; + double J3 = getArea( P( 2 ), P( 3 ), P( 4 ) ) / 2; + double J4 = getArea( P( 3 ), P( 4 ), P( 1 ) ) / 2; + + double JA = 0.25 * ( J1 + J2 + J3 + J4 ); + + double T1 = fabs( ( J1 - JA ) / JA ); + double T2 = fabs( ( J2 - JA ) / JA ); + double T3 = fabs( ( J3 - JA ) / JA ); + double T4 = fabs( ( J4 - JA ) / JA ); + + return Max( Max( T1, T2 ), Max( T3, T4 ) ); +} + +int Taper_i::GetType() const +{ + return SMDSAbs_Face; +} + +/* + Class : Skew_i + Description : Functor for calculating skew in degrees +*/ + +static inline double skewAngle( const gp_XYZ& p1, const gp_XYZ& p2, const gp_XYZ& p3 ) +{ + gp_XYZ p12 = ( p2 + p1 ) / 2; + gp_XYZ p23 = ( p3 + p2 ) / 2; + gp_XYZ p31 = ( p3 + p1 ) / 2; + + return gp_Vec( p31 - p2 ).Angle( p12 - p23 ); +} + +CORBA::Double Skew_i::GetValue( CORBA::Long theId ) +{ + TColgp_SequenceOfXYZ P; + if ( !getPoints( theId, P ) || P.Length() != 3 && P.Length() != 4 ) + return 0; + + // Compute skew + static double PI2 = PI / 2; + if ( P.Length() == 3 ) + { + double A0 = fabs( PI2 - skewAngle( P( 3 ), P( 1 ), P( 2 ) ) ); + double A1 = fabs( PI2 - skewAngle( P( 1 ), P( 2 ), P( 3 ) ) ); + double A2 = fabs( PI2 - skewAngle( P( 2 ), P( 3 ), P( 1 ) ) ); + + return Max( A0, Max( A1, A2 ) ) * 180 / PI; + } + else + { + gp_XYZ p12 = ( P( 1 ) + P( 2 ) ) / 2; + gp_XYZ p23 = ( P( 2 ) + P( 3 ) ) / 2; + gp_XYZ p34 = ( P( 3 ) + P( 4 ) ) / 2; + gp_XYZ p41 = ( P( 4 ) + P( 1 ) ) / 2; + + double A = fabs( PI2 - gp_Vec( p34 - p12 ).Angle( p23 - p41 ) ); + + return A * 180 / PI; + } +} + +int Skew_i::GetType() const +{ + return SMDSAbs_Face; +} + +/* + Class : Area_i + Description : Functor for calculating area +*/ + +CORBA::Double Area_i::GetValue( CORBA::Long theId ) +{ + TColgp_SequenceOfXYZ P; + if ( !getPoints( theId, P ) || P.Length() != 3 && P.Length() != 4 ) + return 0; + + if ( P.Length() == 3 ) + return getArea( P( 1 ), P( 2 ), P( 3 ) ); + else + return getArea( P( 1 ), P( 2 ), P( 3 ) ) + getArea( P( 1 ), P( 3 ), P( 4 ) ); +} + +int Area_i::GetType() const +{ + return SMDSAbs_Face; +} + +/* + Class : Length_i + Description : Functor for calculating length off edge +*/ + +CORBA::Double Length_i::GetValue( CORBA::Long theId ) +{ + TColgp_SequenceOfXYZ P; + return getPoints( theId, P ) && P.Length() == 2 ? getDistance( P( 1 ), P( 2 ) ) : 0; +} + +int Length_i::GetType() const +{ + return SMDSAbs_Edge; +} + +/* + Class : MultiConnection_i + Description : Functor for calculating number of faces conneted to the edge +*/ + +CORBA::Double MultiConnection_i::GetValue( CORBA::Long theId ) +{ + return getNbMultiConnection( myMesh, theId ); +} + +int MultiConnection_i::GetType() const +{ + return SMDSAbs_Edge; +} + +/* + PREDICATES +*/ + +/* + Class : Predicate_i + Description : Base class for all predicates +*/ +Predicate_i::Predicate_i() +: SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() ) +{ + SMESH_Gen_i::GetPOA()->activate_object( this ); +} + + +/* + Class : FreeBorders_i + Description : Predicate for free borders +*/ + +FreeBorders_i::FreeBorders_i() +{ + myMesh = 0; +} + +void FreeBorders_i::SetMesh( SMESH_Mesh_ptr theMesh ) +{ + SMESH_Mesh_i* anImplPtr = + dynamic_cast( SMESH_Gen_i::GetServant( theMesh ).in() ); + myMesh = anImplPtr ? anImplPtr->GetImpl().GetMeshDS() : 0; +} + +CORBA::Boolean FreeBorders_i::IsSatisfy( CORBA::Long theId ) +{ + return getNbMultiConnection( myMesh, theId ) == 1; +} + +int FreeBorders_i::GetType() const +{ + return SMDSAbs_Edge; +} + +/* + Class : Comparator_i + Description : Base class for comparators +*/ + +Comparator_i::Comparator_i() +{ + myMargin = 0; + myFunctor = 0; +} + +Comparator_i::~Comparator_i() +{ + if ( myFunctor != 0 ) + myFunctor->Destroy(); +} + +void Comparator_i::SetMesh( SMESH_Mesh_ptr theMesh ) +{ + if ( myFunctor != 0 ) + myFunctor->SetMesh( theMesh ); +} + +void Comparator_i::SetMargin( CORBA::Double theValue ) +{ + myMargin = theValue; +} + +void Comparator_i::SetNumFunctor( NumericalFunctor_ptr theFunct ) +{ + if ( myFunctor != 0 ) + myFunctor->Destroy(); + + myFunctor = dynamic_cast( SMESH_Gen_i::GetServant( theFunct ).in() ); + + if ( myFunctor != 0 ) + myFunctor->Register(); +} + +int Comparator_i::GetType() const +{ + return myFunctor != 0 ? myFunctor->GetType() : SMDSAbs_All; +} + +/* + Class : LessThan_i + Description : Comparator "<" +*/ + +CORBA::Boolean LessThan_i::IsSatisfy( CORBA::Long theId ) +{ + return myFunctor != 0 && myFunctor->GetValue( theId ) < myMargin; +} + +/* + Class : MoreThan_i + Description : Comparator ">" +*/ + +CORBA::Boolean MoreThan_i::IsSatisfy( CORBA::Long theId ) +{ + return myFunctor != 0 && myFunctor->GetValue( theId ) > myMargin; +} + +/* + Class : EqualTo_i + Description : Comparator "=" +*/ +EqualTo_i::EqualTo_i() +{ + myToler = Precision::Confusion(); +} + +CORBA::Boolean EqualTo_i::IsSatisfy( CORBA::Long theId ) +{ + return myFunctor != 0 && fabs( myFunctor->GetValue( theId ) - myMargin ) < myToler; +} + +void EqualTo_i::SetTolerance( CORBA::Double theToler ) +{ + myToler = theToler; +} + + +/* + Class : LogicalNOT_i + Description : Logical NOT predicate +*/ + +LogicalNOT_i::LogicalNOT_i() +{ + myPredicate = 0; +} + +LogicalNOT_i::~LogicalNOT_i() +{ + if ( myPredicate ) + myPredicate->Destroy(); +} + +CORBA::Boolean LogicalNOT_i::IsSatisfy( CORBA::Long theId ) +{ + return myPredicate !=0 && !myPredicate->IsSatisfy( theId ); +} + +void LogicalNOT_i::SetMesh( SMESH_Mesh_ptr theMesh ) +{ + if ( myPredicate != 0 ) + myPredicate->SetMesh( theMesh ); +} + +void LogicalNOT_i::SetPredicate( Predicate_ptr thePred ) +{ + if ( myPredicate != 0 ) + myPredicate->Destroy(); + + myPredicate = dynamic_cast( SMESH_Gen_i::GetServant( thePred ).in() ); + + if ( myPredicate != 0 ) + myPredicate->Register(); +} + +int LogicalNOT_i::GetType() const +{ + return myPredicate != 0 ? myPredicate->GetType() : SMDSAbs_All; +} + + +/* + Class : LogicalBinary_i + Description : Base class for binary logical predicate +*/ + +LogicalBinary_i::LogicalBinary_i() +{ + myPredicate1 = 0; + myPredicate2 = 0; +} +LogicalBinary_i::~LogicalBinary_i() +{ + if ( myPredicate1 != 0 ) + myPredicate1->Destroy(); + + if ( myPredicate2 != 0 ) + myPredicate2->Destroy(); +} + +void LogicalBinary_i::SetMesh( SMESH_Mesh_ptr theMesh ) +{ + if ( myPredicate1 != 0 ) + myPredicate1->SetMesh( theMesh ); + + if ( myPredicate2 != 0 ) + myPredicate2->SetMesh( theMesh ); +} + +void LogicalBinary_i::SetPredicate1( Predicate_ptr thePredicate ) +{ + if ( myPredicate1 != 0 ) + myPredicate1->Destroy(); + + myPredicate1 = dynamic_cast( SMESH_Gen_i::GetServant( thePredicate ).in() ); + + if ( myPredicate1 != 0 ) + myPredicate1->Register(); +} + +void LogicalBinary_i::SetPredicate2( Predicate_ptr thePredicate ) +{ + if ( myPredicate2 != 0 ) + myPredicate2->Destroy(); + + myPredicate2 = dynamic_cast( SMESH_Gen_i::GetServant( thePredicate ).in() ); + + if ( myPredicate2 != 0 ) + myPredicate2->Register(); +} + +int LogicalBinary_i::GetType() const +{ + if ( myPredicate1 == 0 || myPredicate2 == 0 ) + return SMDSAbs_All; + + int aType1 = myPredicate1->GetType(); + int aType2 = myPredicate2->GetType(); + + return aType1 == aType2 ? aType1 : SMDSAbs_All; +} + +/* + Class : LogicalAND_i + Description : Logical AND +*/ + +CORBA::Boolean LogicalAND_i::IsSatisfy( CORBA::Long theId ) +{ + return myPredicate1 != 0 && + myPredicate2 != 0 && + myPredicate1->IsSatisfy( theId ) && myPredicate2->IsSatisfy( theId );; +} + +/* + Class : LogicalOR_i + Description : Logical OR +*/ + +CORBA::Boolean LogicalOR_i::IsSatisfy( CORBA::Long theId ) +{ + return myPredicate1 != 0 && + myPredicate2 != 0 && + myPredicate1->IsSatisfy( theId ) || myPredicate2->IsSatisfy( theId ); +} + + +/* + FILTER +*/ + +Filter_i::Filter_i() +{ + myPredicate = 0; +} + +Filter_i::~Filter_i() +{ + if ( myPredicate != 0 ) + myPredicate->Destroy(); +} + +void Filter_i::SetPredicate( Predicate_ptr thePredicate ) +{ + if ( myPredicate != 0 ) + myPredicate->Destroy(); + + myPredicate = dynamic_cast( SMESH_Gen_i::GetServant( thePredicate ).in() ); + + if ( myPredicate != 0 ) + myPredicate->Register(); +} + +void Filter_i::SetMesh( SMESH_Mesh_ptr theMesh ) +{ + if ( myPredicate != 0 ) + myPredicate->SetMesh( theMesh ); +} + +SMESH::long_array* Filter_i::GetElementsId( SMESH_Mesh_ptr theMesh ) +{ + + SetMesh( theMesh ); + + SMESH_Mesh_i* anImplPtr = + dynamic_cast( SMESH_Gen_i::GetServant( theMesh ).in() ); + + TColStd_ListOfInteger aList; + + if ( anImplPtr != 0 ) + { + SMESHDS_Mesh* aMesh = anImplPtr->GetImpl().GetMeshDS(); + + if ( myPredicate != 0 ) + { + int aType = myPredicate->GetType(); + + if ( aType == SMDSAbs_Edge ) + { + SMDS_EdgeIteratorPtr anIter = aMesh->edgesIterator(); + if ( anIter != 0 ) + { + while( anIter->more() ) + { + const SMDS_MeshElement* anElem = anIter->next(); + if ( myPredicate->IsSatisfy( anElem->GetID() ) ) + aList.Append( anElem->GetID() ); + } + } +// delete anIter; + } + else if ( aType == SMDSAbs_Face ) + { + SMDS_FaceIteratorPtr anIter = aMesh->facesIterator(); + if ( anIter != 0 ) + { + while( anIter->more() ) + { + const SMDS_MeshElement* anElem = anIter->next(); + if ( myPredicate->IsSatisfy( anElem->GetID() ) ) + aList.Append( anElem->GetID() ); + } + } +// delete anIter; + } + } + } + + SMESH::long_array_var anArray = new SMESH::long_array; + + anArray->length( aList.Extent() ); + TColStd_ListIteratorOfListOfInteger anIter( aList ); + int i = 0; + for( ; anIter.More(); anIter.Next() ) + anArray[ i++ ] = anIter.Value(); + + return anArray._retn(); +} + +/* + FILTER MANAGER +*/ + +FilterManager_i::FilterManager_i() +: SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() ) +{ + SMESH_Gen_i::GetPOA()->activate_object( this ); +} + +MinimumAngle_ptr FilterManager_i::CreateMinimumAngle() +{ + SMESH::MinimumAngle_i* aServant = new SMESH::MinimumAngle_i(); + SMESH::MinimumAngle_var anObj = aServant->_this(); + return anObj._retn(); +} + + +AspectRatio_ptr FilterManager_i::CreateAspectRatio() +{ + SMESH::AspectRatio_i* aServant = new SMESH::AspectRatio_i(); + SMESH::AspectRatio_var anObj = aServant->_this(); + return anObj._retn(); +} + + +Warping_ptr FilterManager_i::CreateWarping() +{ + SMESH::Warping_i* aServant = new SMESH::Warping_i(); + SMESH::Warping_var anObj = aServant->_this(); + return anObj._retn(); +} + + +Taper_ptr FilterManager_i::CreateTaper() +{ + SMESH::Taper_i* aServant = new SMESH::Taper_i(); + SMESH::Taper_var anObj = aServant->_this(); + return anObj._retn(); +} + + +Skew_ptr FilterManager_i::CreateSkew() +{ + SMESH::Skew_i* aServant = new SMESH::Skew_i(); + SMESH::Skew_var anObj = aServant->_this(); + return anObj._retn(); +} + + +Area_ptr FilterManager_i::CreateArea() +{ + SMESH::Area_i* aServant = new SMESH::Area_i(); + SMESH::Area_var anObj = aServant->_this(); + return anObj._retn(); +} + + +Length_ptr FilterManager_i::CreateLength() +{ + SMESH::Length_i* aServant = new SMESH::Length_i(); + SMESH::Length_var anObj = aServant->_this(); + return anObj._retn(); +} + + +MultiConnection_ptr FilterManager_i::CreateMultiConnection() +{ + SMESH::MultiConnection_i* aServant = new SMESH::MultiConnection_i(); + SMESH::MultiConnection_var anObj = aServant->_this(); + return anObj._retn(); +} + + +FreeBorders_ptr FilterManager_i::CreateFreeBorders() +{ + SMESH::FreeBorders_i* aServant = new SMESH::FreeBorders_i(); + SMESH::FreeBorders_var anObj = aServant->_this(); + return anObj._retn(); +} + +LessThan_ptr FilterManager_i::CreateLessThan() +{ + SMESH::LessThan_i* aServant = new SMESH::LessThan_i(); + SMESH::LessThan_var anObj = aServant->_this(); + return anObj._retn(); +} + + +MoreThan_ptr FilterManager_i::CreateMoreThan() +{ + SMESH::MoreThan_i* aServant = new SMESH::MoreThan_i(); + SMESH::MoreThan_var anObj = aServant->_this(); + return anObj._retn(); +} + +EqualTo_ptr FilterManager_i::CreateEqualTo() +{ + SMESH::EqualTo_i* aServant = new SMESH::EqualTo_i(); + SMESH::EqualTo_var anObj = aServant->_this(); + return anObj._retn(); +} + + +LogicalNOT_ptr FilterManager_i::CreateLogicalNOT() +{ + SMESH::LogicalNOT_i* aServant = new SMESH::LogicalNOT_i(); + SMESH::LogicalNOT_var anObj = aServant->_this(); + return anObj._retn(); +} + + +LogicalAND_ptr FilterManager_i::CreateLogicalAND() +{ + SMESH::LogicalAND_i* aServant = new SMESH::LogicalAND_i(); + SMESH::LogicalAND_var anObj = aServant->_this(); + return anObj._retn(); +} + + +LogicalOR_ptr FilterManager_i::CreateLogicalOR() +{ + SMESH::LogicalOR_i* aServant = new SMESH::LogicalOR_i(); + SMESH::LogicalOR_var anObj = aServant->_this(); + return anObj._retn(); +} + +Filter_ptr FilterManager_i::CreateFilter() +{ + SMESH::Filter_i* aServant = new SMESH::Filter_i(); + SMESH::Filter_var anObj = aServant->_this(); + return anObj._retn(); +} diff --git a/src/SMESH_I/SMESH_Filter_i.hxx b/src/SMESH_I/SMESH_Filter_i.hxx new file mode 100644 index 000000000..26edd5b72 --- /dev/null +++ b/src/SMESH_I/SMESH_Filter_i.hxx @@ -0,0 +1,417 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_Filter_i.hxx +// Author : Alexey Petrov, OCC +// Module : SMESH + +#ifndef _SMESH_FILTER_I_HXX_ +#define _SMESH_FILTER_I_HXX_ + +#include +#include CORBA_SERVER_HEADER(SMESH_Filter) +#include "SALOME_GenericObj_i.hh" + +class SMESHDS_Mesh; +class gp_Pnt; +class gp_XYZ; +class TColgp_SequenceOfXYZ; + +namespace SMESH{ + +/* + FUNCTORS +*/ + +/* + Class : NumericalFunctor_i + Description : Base class for numerical functors + + PortableServer::POA_ptr thePOA + +*/ + +class NumericalFunctor_i: public virtual POA_SMESH::NumericalFunctor, + public virtual SALOME::GenericObj_i +{ +public: + NumericalFunctor_i(); + void SetMesh( SMESH_Mesh_ptr theMesh ); + virtual int GetType() const = 0; + +protected: + bool getPoints( const int theId, + TColgp_SequenceOfXYZ& theRes ) const; +protected: + SMESHDS_Mesh* myMesh; +}; + +/* + Class : SMESH_MinimumAngleFunct + Description : Functor for calculation of minimum angle +*/ + +class MinimumAngle_i: public virtual POA_SMESH::MinimumAngle, + public virtual NumericalFunctor_i +{ +public: + CORBA::Double GetValue( CORBA::Long theElementId ); + virtual int GetType() const; +}; + +/* + Class : AspectRatio_i + Description : Functor for calculating aspect ratio +*/ + +class AspectRatio_i: public virtual POA_SMESH::AspectRatio, + public virtual NumericalFunctor_i +{ +public: + CORBA::Double GetValue(CORBA::Long theElementId); + virtual int GetType() const; +}; + +/* + Class : Warping_i + Description : Functor for calculating warping +*/ + +class Warping_i: public virtual POA_SMESH::Warping, + public virtual NumericalFunctor_i +{ +public: + CORBA::Double GetValue(CORBA::Long theElementId); + virtual int GetType() const; + +private: + double ComputeA( const gp_XYZ&, const gp_XYZ&, + const gp_XYZ&, const gp_XYZ& ) const; +}; + +/* + Class : Taper_i + Description : Functor for calculating taper +*/ + +class Taper_i: public virtual POA_SMESH::Taper, + public virtual NumericalFunctor_i +{ +public: + CORBA::Double GetValue( CORBA::Long theElementId ); + virtual int GetType() const; +}; + +/* + Class : Skew_i + Description : Functor for calculating skew in degrees +*/ + +class Skew_i: public virtual POA_SMESH::Skew, + public virtual NumericalFunctor_i +{ +public: + CORBA::Double GetValue( CORBA::Long theElementId ); + virtual int GetType() const; +}; + +/* + Class : Area_i + Description : Functor for calculating area +*/ + +class Area_i: public virtual POA_SMESH::Area, + public virtual NumericalFunctor_i +{ +public: + CORBA::Double GetValue( CORBA::Long theElementId ); + virtual int GetType() const; +}; + +/* + Class : Length_i + Description : Functor for calculating length of edge +*/ + +class Length_i: public virtual POA_SMESH::Length, + public virtual NumericalFunctor_i +{ +public: + CORBA::Double GetValue( CORBA::Long theElementId ); + virtual int GetType() const; +}; + +/* + Class : MultiConnection_i + Description : Functor for calculating number of faces conneted to the edge +*/ + +class MultiConnection_i: public virtual POA_SMESH::MultiConnection, + public virtual NumericalFunctor_i +{ +public: + CORBA::Double GetValue( CORBA::Long theElementId ); + virtual int GetType() const; +}; + + +/* + PREDICATES +*/ + +/* + Class : Predicate_i + Description : Base class for all predicates +*/ + +class Predicate_i: public virtual POA_SMESH::Predicate, + public virtual SALOME::GenericObj_i +{ +public: + Predicate_i(); + virtual int GetType() const = 0; +}; + + +/* + Class : FreeBorders_i + Description : Predicate for free borders +*/ + +class FreeBorders_i: public virtual POA_SMESH::FreeBorders, + public virtual Predicate_i +{ +public: + FreeBorders_i(); + void SetMesh( SMESH_Mesh_ptr theMesh ); + CORBA::Boolean IsSatisfy( CORBA::Long theElementId ); + virtual int GetType() const; + +protected: + SMESHDS_Mesh* myMesh; +}; + +/* + Class : Comparator_i + Description : Base class for comparators +*/ + +class Comparator_i: public virtual POA_SMESH::Comparator, + public virtual Predicate_i +{ +public: + Comparator_i(); + virtual ~Comparator_i(); + + void SetMesh( SMESH_Mesh_ptr theMesh ); + void SetMargin( CORBA::Double ); + void SetNumFunctor( NumericalFunctor_ptr ); + + virtual int GetType() const; + +protected: + CORBA::Double myMargin; + NumericalFunctor_i* myFunctor; +}; + +/* + Class : LessThan_i + Description : Comparator "<" +*/ + +class LessThan_i: public virtual POA_SMESH::LessThan, + public virtual Comparator_i +{ +public: + CORBA::Boolean IsSatisfy( CORBA::Long theElementId ); +}; + +/* + Class : MoreThan_i + Description : Comparator ">" +*/ +class MoreThan_i: public virtual POA_SMESH::MoreThan, + public virtual Comparator_i +{ +public: + CORBA::Boolean IsSatisfy( CORBA::Long theElementId ); +}; + +/* + Class : EqualTo_i + Description : Comparator "=" +*/ +class EqualTo_i: public virtual POA_SMESH::EqualTo, + public virtual Comparator_i +{ +public: + EqualTo_i(); + + CORBA::Boolean IsSatisfy( CORBA::Long theElementId ); + + void SetTolerance( CORBA::Double ); + +private: + CORBA::Double myToler; +}; + +/* + Class : Logical_i + Description : Base class for logical predicate +*/ + +class Logical_i: public virtual POA_SMESH::Logical, + public virtual Predicate_i + +{ +}; + +/* + Class : LogicalNOT_i + Description : Logical NOT predicate +*/ + +class LogicalNOT_i: public virtual POA_SMESH::LogicalNOT, + public virtual Logical_i +{ +public: + LogicalNOT_i(); + virtual ~LogicalNOT_i(); + + CORBA::Boolean IsSatisfy( CORBA::Long ); + + void SetMesh( SMESH_Mesh_ptr ); + void SetPredicate( Predicate_ptr ); + + virtual int GetType() const; + +private: + Predicate_i* myPredicate; +}; + + +/* + Class : LogicalBinary_i + Description : Base class for binary logical predicate +*/ + +class LogicalBinary_i: public virtual POA_SMESH::LogicalBinary, + public virtual Logical_i +{ +public: + LogicalBinary_i(); + virtual ~LogicalBinary_i(); + + void SetMesh( SMESH_Mesh_ptr ); + + void SetPredicate1( Predicate_ptr ); + void SetPredicate2( Predicate_ptr ); + + virtual int GetType() const; + +protected: + Predicate_i* myPredicate1; + Predicate_i* myPredicate2; +}; + +/* + Class : LogicalAND_i + Description : Logical AND +*/ + +class LogicalAND_i: public virtual POA_SMESH::LogicalAND, + public virtual LogicalBinary_i +{ +public: + CORBA::Boolean IsSatisfy( CORBA::Long theElementId ); +}; + +/* + Class : LogicalOR_i + Description : Logical OR +*/ + +class LogicalOR_i: public virtual POA_SMESH::LogicalOR, + public virtual LogicalBinary_i +{ +public: + CORBA::Boolean IsSatisfy( CORBA::Long theElementId ); +}; + + +/* + FILTER +*/ + +class Filter_i: public virtual POA_SMESH::Filter, + public virtual SALOME::GenericObj_i +{ +public: + Filter_i(); + virtual ~Filter_i(); + void SetPredicate(Predicate_ptr ); + long_array* GetElementsId(SMESH_Mesh_ptr ); + void SetMesh( SMESH_Mesh_ptr ); + +protected: + Predicate_i* myPredicate; +}; + + +/* + FILTER MANAGER +*/ + +class FilterManager_i: public virtual POA_SMESH::FilterManager, + public virtual SALOME::GenericObj_i +{ +public: + FilterManager_i(); + MinimumAngle_ptr CreateMinimumAngle(); + AspectRatio_ptr CreateAspectRatio(); + Warping_ptr CreateWarping(); + Taper_ptr CreateTaper(); + Skew_ptr CreateSkew(); + Area_ptr CreateArea(); + Length_ptr CreateLength(); + MultiConnection_ptr CreateMultiConnection(); + + FreeBorders_ptr CreateFreeBorders(); + + LessThan_ptr CreateLessThan(); + MoreThan_ptr CreateMoreThan(); + EqualTo_ptr CreateEqualTo(); + + LogicalNOT_ptr CreateLogicalNOT(); + LogicalAND_ptr CreateLogicalAND(); + LogicalOR_ptr CreateLogicalOR(); + + Filter_ptr CreateFilter(); +}; + + + +}; + + +#endif diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index 0d77f8726..44cbd411e 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -26,6 +26,7 @@ // Module : SMESH // $Header$ +using namespace std; #include #include #include @@ -40,21 +41,41 @@ #include #include #include +#include #include #include #include -#include "SMESH_Gen_i.hxx" -#include "SMESH_Mesh_i.hxx" -#include "SMESH_LocalLength_i.hxx" -#include "SMESH_NumberOfSegments_i.hxx" -#include "SMESH_MaxElementArea_i.hxx" -#include "SMESH_MaxElementVolume_i.hxx" - -#include "SMESHDriver.h" - #include "Utils_CorbaException.hxx" + #include "utilities.h" +#include +#include +#include + +#include + +#include "SMESH_Gen_i.hxx" +#include "SMESH_Mesh_i.hxx" +#include "SMESH_Hypothesis_i.hxx" +#include "SMESH_Algo_i.hxx" +#include "SMESH_Group_i.hxx" + +#include "SMESHDS_Document.hxx" +#include "SMESHDS_Group.hxx" +#include "SMESH_topo.hxx" +#include "SMESH_Group.hxx" + +#include CORBA_SERVER_HEADER(SMESH_Group) +#include CORBA_SERVER_HEADER(SMESH_Filter) +#include "SMESH_Filter_i.hxx" + +#include "Document_Reader.h" +#include "DriverMED_W_SMESHDS_Mesh.h" +#include "DriverMED_R_SMESHDS_Mesh.h" +#include "DriverMED_R_SMESHDS_Document.h" +#include "DriverUNV_R_SMESHDS_Document.h" +#include "DriverDAT_R_SMESHDS_Document.h" #include "SALOMEDS_Tool.hxx" #include "SALOME_NamingService.hxx" @@ -62,1926 +83,2424 @@ #include "Utils_SINGLETON.hxx" #include "OpUtil.hxx" -//#include +#include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog) #include "GEOM_Client.hxx" +#include "Utils_ExceptHandlers.hxx" #include -#include -#include -using namespace std; - -#define NUM_TMP_FILES 4 - -// Tags definition -long Tag_HypothesisRoot = 1; -long Tag_AlgorithmsRoot = 2; -long Tag_RefOnShape = 1; -long Tag_RefOnAppliedHypothesis = 2; -long Tag_RefOnAppliedAlgorithms = 3; - -long Tag_SubMeshOnVertex = 4; -long Tag_SubMeshOnEdge = 5; -long Tag_SubMeshOnFace = 6; -long Tag_SubMeshOnSolid = 7; -long Tag_SubMeshOnCompound = 8; +#define NUM_TMP_FILES 2 + +// Tags definition =========================================================== +// Top level +long Tag_HypothesisRoot = 1; // hypotheses root +long Tag_AlgorithmsRoot = 2; // algorithms root +// Mesh/Submesh +long Tag_RefOnShape = 1; // references to shape +long Tag_RefOnAppliedHypothesis = 2; // applied hypotheses root +long Tag_RefOnAppliedAlgorithms = 3; // applied algorithms root +// Mesh only +long Tag_SubMeshOnVertex = 4; // sub-meshes roots by type +long Tag_SubMeshOnEdge = 5; // ... +long Tag_SubMeshOnFace = 6; // ... +long Tag_SubMeshOnSolid = 7; // ... +long Tag_SubMeshOnCompound = 8; // ... +long Tag_NodeGroups = 9; // Group roots by type +long Tag_EdgeGroups = 10; // ... +long Tag_FaceGroups = 11; // ... +long Tag_VolumeGroups = 12; // ... +// =========================================================================== + +// Static variables definition +CORBA::ORB_var SMESH_Gen_i::myOrb; +PortableServer::POA_var SMESH_Gen_i::myPoa; +SALOME_NamingService* SMESH_Gen_i::myNS = NULL; +SALOME_LifeCycleCORBA* SMESH_Gen_i::myLCC = NULL; //============================================================================= /*! - * default constructor: not for use + * FindMaxChildTag [ static internal ] + * + * Finds maximum child tag for the given object */ //============================================================================= -SMESH_Gen_i::SMESH_Gen_i() +static long FindMaxChildTag( SALOMEDS::SObject_ptr theSObject ) { - MESSAGE("SMESH_Gen_i default constructor"); - // **** + long aTag = 0; + if ( !theSObject->_is_nil() ) { + SALOMEDS::Study_var aStudy = theSObject->GetStudy(); + if ( !aStudy->_is_nil() ) { + SALOMEDS::ChildIterator_var anIter = aStudy->NewChildIterator( theSObject ); + for ( ; anIter->More(); anIter->Next() ) { + long nTag = anIter->Value()->Tag(); + if ( nTag > aTag ) + aTag = nTag; + } + } + } + return aTag; } //============================================================================= /*! - * Standard constructor, used with Container. + * Get...Tag [ static ] + * + * Methods which determine SMESH data model structure */ //============================================================================= -SMESH_Gen_i::SMESH_Gen_i(CORBA::ORB_ptr orb, - PortableServer::POA_ptr poa, - PortableServer::ObjectId * contId, - const char *instanceName, - const char *interfaceName):Engines_Component_i(orb, poa, contId, - instanceName, interfaceName) +long SMESH_Gen_i::GetHypothesisRootTag() { - MESSAGE("activate object"); - _thisObj = this; - _id = _poa->activate_object(_thisObj); - - _ShapeReader = NULL; - + return Tag_HypothesisRoot; } -//============================================================================= -/*! - * Standard destructor - */ -//============================================================================= - -SMESH_Gen_i::~SMESH_Gen_i() +long SMESH_Gen_i::GetAlgorithmsRootTag() { - MESSAGE("~SMESH_Gen_i"); - // **** + return Tag_AlgorithmsRoot; } -//============================================================================= -/*! - * - */ -//============================================================================= - -SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::CreateHypothesis(const char *anHyp, - CORBA::Long studyId) throw(SALOME::SALOME_Exception) +long SMESH_Gen_i::GetRefOnShapeTag() { - MESSAGE("CreateHypothesis"); - - // create a new hypothesis object servant - - SMESH_Hypothesis_i *myHypothesis_i = 0; - try - { - myHypothesis_i = _hypothesisFactory_i.Create(anHyp, studyId, &_impl); - } - catch(SALOME_Exception & S_ex) - { - THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); - } - - // activate the CORBA servant of hypothesis - - SMESH::SMESH_Hypothesis_var hypothesis_i - = SMESH::SMESH_Hypothesis::_narrow(myHypothesis_i->_this()); - return SMESH::SMESH_Hypothesis::_duplicate(hypothesis_i); + return Tag_RefOnShape; } -/** - * CORBA implementation of SMESH_Gen::Init. See SMESH_Gen.idl. - */ -SMESH::SMESH_Mesh_ptr SMESH_Gen_i::Init(GEOM::GEOM_Gen_ptr geomEngine, - CORBA::Long studyId, - GEOM::GEOM_Shape_ptr aShape) throw(SALOME::SALOME_Exception) +long SMESH_Gen_i::GetRefOnAppliedHypothesisTag() { - return Init(geomEngine, studyId, aShape, -1); + return Tag_RefOnAppliedHypothesis; } -/** - * This is NOT a CORBA implementation. Differ from the Init CORBA method - * by allowing to specify the ID of the created mesh. - */ -SMESH::SMESH_Mesh_ptr SMESH_Gen_i::Init(GEOM::GEOM_Gen_ptr geomEngine, - CORBA::Long studyId, GEOM::GEOM_Shape_ptr aShape, int meshID) - throw(SALOME::SALOME_Exception) +long SMESH_Gen_i::GetRefOnAppliedAlgorithmsTag() { - MESSAGE("Init"); - // _narrow() duplicates the reference and checks the type - GEOM::GEOM_Gen_var geom = GEOM::GEOM_Gen::_narrow(geomEngine); - GEOM::GEOM_Shape_var myShape = GEOM::GEOM_Shape::_narrow(aShape); - - if (CORBA::is_nil(geom)) - THROW_SALOME_CORBA_EXCEPTION("bad geom reference", SALOME::BAD_PARAM); - if (CORBA::is_nil(myShape)) - THROW_SALOME_CORBA_EXCEPTION("bad shape reference", SALOME::BAD_PARAM); - - // Get or create the GEOM_Client instance - - SMESH_Mesh_i *meshServant = 0; - try - { - if (!_ShapeReader) - _ShapeReader = new GEOM_Client(); - ASSERT(_ShapeReader); + return Tag_RefOnAppliedAlgorithms; +} - // explore main Shape, get local TopoDS_Shapes of all subShapes - // SMESH_topo* myTopo = ExploreMainShape(geom, studyId, myShape); +long SMESH_Gen_i::GetSubMeshOnVertexTag() +{ + return Tag_SubMeshOnVertex; +} - // Get studyContext_i, create it if it does'nt exist +long SMESH_Gen_i::GetSubMeshOnEdgeTag() +{ + return Tag_SubMeshOnEdge; +} - if (_mapStudyContext_i.find(studyId) == _mapStudyContext_i.end()) - { - _mapStudyContext_i[studyId] = new StudyContext_iStruct; - } - StudyContext_iStruct *myStudyContext = _mapStudyContext_i[studyId]; +long SMESH_Gen_i::GetSubMeshOnFaceTag() +{ + return Tag_SubMeshOnFace; +} - // create a new mesh object - TopoDS_Shape myLocShape = _ShapeReader->GetShape(geom, myShape); - SMESH_Mesh * meshImpl=_impl.Init(studyId, myLocShape, meshID); +long SMESH_Gen_i::GetSubMeshOnSolidTag() +{ + return Tag_SubMeshOnSolid; +} - // create a new mesh object servant, store it in a map in study context - meshServant = new SMESH_Mesh_i(this, geom, studyId, meshImpl); - myStudyContext->mapMesh_i[meshServant->GetId()] = meshServant; - } - catch(SALOME_Exception & S_ex) - { - THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); - } +long SMESH_Gen_i::GetSubMeshOnCompoundTag() +{ + return Tag_SubMeshOnCompound; +} - // activate the CORBA servant of Mesh +long SMESH_Gen_i::GetNodeGroupsTag() +{ + return Tag_NodeGroups; +} - SMESH::SMESH_Mesh_var mesh - = SMESH::SMESH_Mesh::_narrow(meshServant->_this()); +long SMESH_Gen_i::GetEdgeGroupsTag() +{ + return Tag_EdgeGroups; +} - meshServant->SetIor(mesh); +long SMESH_Gen_i::GetFaceGroupsTag() +{ + return Tag_FaceGroups; +} - return SMESH::SMESH_Mesh::_duplicate(mesh); +long SMESH_Gen_i::GetVolumeGroupsTag() +{ + return Tag_VolumeGroups; } //============================================================================= /*! - * + * GetServant [ static ] + * + * Get servant of the CORBA object */ //============================================================================= -CORBA::Boolean SMESH_Gen_i::IsReadyToCompute(SMESH::SMESH_Mesh_ptr aMesh, - GEOM::GEOM_Shape_ptr aShape) throw(SALOME::SALOME_Exception) +PortableServer::ServantBase_var SMESH_Gen_i::GetServant( CORBA::Object_ptr theObject ) { - MESSAGE("SMESH_Gen_i::IsReadyToCompute"); - return true; + if( CORBA::is_nil( theObject ) || CORBA::is_nil( GetPOA() ) ) + return NULL; + try { + PortableServer::Servant aServant = GetPOA()->reference_to_servant( theObject ); + return aServant; + } + catch (...) { + MESSAGE( "GetServant - Unknown exception was caught!!!" ); + return NULL; + } } //============================================================================= /*! - * + * SObjectToObject [ static ] + * + * Get CORBA object corresponding to the SALOMEDS::SObject */ //============================================================================= -SMESH::long_array * - SMESH_Gen_i::GetSubShapesId(GEOM::GEOM_Gen_ptr geomEngine, - CORBA::Long studyId, - GEOM::GEOM_Shape_ptr mainShape, - const SMESH::shape_array & listOfSubShape)throw(SALOME::SALOME_Exception) +CORBA::Object_var SMESH_Gen_i::SObjectToObject( SALOMEDS::SObject_ptr theSObject ) { - MESSAGE("SMESH_Gen_i::GetSubShapesId"); - SMESH::long_array_var shapesId = new SMESH::long_array; - set < int >setId; - - GEOM::GEOM_Gen_var geom = GEOM::GEOM_Gen::_narrow(geomEngine); - GEOM::GEOM_Shape_var myShape = GEOM::GEOM_Shape::_narrow(mainShape); - - if (CORBA::is_nil(geom)) - THROW_SALOME_CORBA_EXCEPTION("bad geom reference", SALOME::BAD_PARAM); - if (CORBA::is_nil(myShape)) - THROW_SALOME_CORBA_EXCEPTION("bad shape reference", SALOME::BAD_PARAM); - - try - { - if (!_ShapeReader) - _ShapeReader = new GEOM_Client(); - ASSERT(_ShapeReader); - TopoDS_Shape myMainShape = _ShapeReader->GetShape(geom, myShape); - TopTools_IndexedMapOfShape myIndexToShape; - TopExp::MapShapes(myMainShape, myIndexToShape); - - for (unsigned int i = 0; i < listOfSubShape.length(); i++) - { - GEOM::GEOM_Shape_var aShape - = GEOM::GEOM_Shape::_narrow(listOfSubShape[i]); - if (CORBA::is_nil(aShape)) - THROW_SALOME_CORBA_EXCEPTION("bad shape reference", - SALOME::BAD_PARAM); - TopoDS_Shape locShape = _ShapeReader->GetShape(geom, aShape); - for (TopExp_Explorer exp(locShape, TopAbs_FACE); exp.More(); - exp.Next()) - { - const TopoDS_Face & F = TopoDS::Face(exp.Current()); - setId.insert(myIndexToShape.FindIndex(F)); - SCRUTE(myIndexToShape.FindIndex(F)); - } - for (TopExp_Explorer exp(locShape, TopAbs_EDGE); exp.More(); - exp.Next()) - { - const TopoDS_Edge & E = TopoDS::Edge(exp.Current()); - setId.insert(myIndexToShape.FindIndex(E)); - SCRUTE(myIndexToShape.FindIndex(E)); - } - for (TopExp_Explorer exp(locShape, TopAbs_VERTEX); exp.More(); - exp.Next()) - { - const TopoDS_Vertex & V = TopoDS::Vertex(exp.Current()); - setId.insert(myIndexToShape.FindIndex(V)); - SCRUTE(myIndexToShape.FindIndex(V)); - } - } - shapesId->length(setId.size()); - set < int >::iterator iind; - int i = 0; - for (iind = setId.begin(); iind != setId.end(); iind++) - { - SCRUTE((*iind)); - shapesId[i] = (*iind); - SCRUTE(shapesId[i]); - i++; - } - } - catch(SALOME_Exception & S_ex) - { - THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); + SALOMEDS::GenericAttribute_var anAttr; + CORBA::Object_var anObj; + if ( !theSObject->_is_nil() ) { + try { + if( theSObject->FindAttribute( anAttr, "AttributeIOR" ) ) { + SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow( anAttr ); + CORBA::String_var aValue = anIOR->Value(); + if( strcmp( aValue, "" ) != 0 ) + anObj = GetORB()->string_to_object( aValue ); } - - return shapesId._retn(); + } + catch( ... ) { + MESSAGE( "SObjectToObject - Unknown exception was caught!!!" ); + } + } + return anObj; } //============================================================================= /*! - * + * GetNS [ static ] + * + * Get SALOME_NamingService object */ //============================================================================= -CORBA::Boolean SMESH_Gen_i::Compute(SMESH::SMESH_Mesh_ptr aMesh, - GEOM::GEOM_Shape_ptr aShape) throw(SALOME::SALOME_Exception) +SALOME_NamingService* SMESH_Gen_i::GetNS() { - MESSAGE("SMESH_Gen_i::Compute"); - GEOM::GEOM_Shape_var myShape = GEOM::GEOM_Shape::_narrow(aShape); - if (CORBA::is_nil(myShape)) - THROW_SALOME_CORBA_EXCEPTION("bad shape reference", SALOME::BAD_PARAM); - - SMESH::SMESH_Mesh_var myMesh = SMESH::SMESH_Mesh::_narrow(aMesh); - if (CORBA::is_nil(myMesh)) - THROW_SALOME_CORBA_EXCEPTION("bad Mesh reference", SALOME::BAD_PARAM); - - bool ret = false; - try - { - - // get study context from studyId given by CORBA mesh object - - int studyId = myMesh->GetStudyId(); - ASSERT(_mapStudyContext_i.find(studyId) != _mapStudyContext_i.end()); - StudyContext_iStruct *myStudyContext = _mapStudyContext_i[studyId]; - - // get local Mesh_i object with Id and study context - - int meshId = myMesh->GetId(); - ASSERT(myStudyContext->mapMesh_i.find(meshId) != - myStudyContext->mapMesh_i.end()); - SMESH_Mesh_i *meshServant = myStudyContext->mapMesh_i[meshId]; - ASSERT(meshServant); - - // get local TopoDS_Shape - - GEOM::GEOM_Gen_var geom = meshServant->GetGeomEngine(); - TopoDS_Shape myLocShape = _ShapeReader->GetShape(geom, myShape); + if ( myNS == NULL ) { + myNS = SINGLETON_::Instance(); + ASSERT(SINGLETON_::IsAlreadyExisting()); + myNS->init_orb( GetORB() ); + } + return myNS; +} - // implementation compute +//============================================================================= +/*! + * GetLCC [ static ] + * + * Get SALOME_LifeCycleCORBA object + */ +//============================================================================= +SALOME_LifeCycleCORBA* SMESH_Gen_i::GetLCC() { + if ( myLCC == NULL ) { + myLCC = new SALOME_LifeCycleCORBA( GetNS() ); + } + return myLCC; +} - ::SMESH_Mesh & myLocMesh = meshServant->GetImpl(); - ret = _impl.Compute(myLocMesh, myLocShape); - } - catch(SALOME_Exception & S_ex) - { - MESSAGE("catch exception " << S_ex.what()); - return false; -// THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); - } - return ret; +//============================================================================= +/*! + * GetGeomEngine [ static ] + * + * Get GEOM::GEOM_Gen reference + */ +//============================================================================= +GEOM::GEOM_Gen_ptr SMESH_Gen_i::GetGeomEngine() { + GEOM::GEOM_Gen_var aGeomEngine = + GEOM::GEOM_Gen::_narrow( GetLCC()->FindOrLoad_Component("FactoryServer","GEOM") ); + return aGeomEngine._retn(); } //============================================================================= /*! - * + * SMESH_Gen_i::SMESH_Gen_i + * + * Default constructor: not for use */ //============================================================================= -SALOMEDS::TMPFile * SMESH_Gen_i::Save(SALOMEDS::SComponent_ptr theComponent, - const char *theURL, bool isMultiFile) +SMESH_Gen_i::SMESH_Gen_i() { - MESSAGE("SMESH_Gen_i::SAVE"); - SALOMEDS::Study_var Study = theComponent->GetStudy(); - int studyId; - - // Declare a byte stream - SALOMEDS::TMPFile_var aStreamFile; - - // Obtain a temporary dir - TCollection_AsciiString tmpDir = - (isMultiFile) ? TCollection_AsciiString((char *)theURL) : - SALOMEDS_Tool::GetTmpDir(); - - // Create a sequence of files processed - SALOMEDS::ListOfFileNames_var aFileSeq = new SALOMEDS::ListOfFileNames; - aFileSeq->length(NUM_TMP_FILES); - - TCollection_AsciiString aStudyName(""); - - if (isMultiFile) - aStudyName = - (SALOMEDS_Tool::GetNameFromPath(theComponent->GetStudy()->URL())); - - // Set names of temporary files - TCollection_AsciiString filename = - aStudyName + TCollection_AsciiString("_SMESH.hdf"); - TCollection_AsciiString hypofile = - aStudyName + TCollection_AsciiString("_SMESH_Hypo.txt"); - TCollection_AsciiString algofile = - aStudyName + TCollection_AsciiString("_SMESH_Algo.txt"); - TCollection_AsciiString meshfile = - aStudyName + TCollection_AsciiString("_SMESH_Mesh.med"); - aFileSeq[0] = CORBA::string_dup(filename.ToCString()); - aFileSeq[1] = CORBA::string_dup(hypofile.ToCString()); - aFileSeq[2] = CORBA::string_dup(algofile.ToCString()); - aFileSeq[3] = CORBA::string_dup(meshfile.ToCString()); - filename = tmpDir + filename; - hypofile = tmpDir + hypofile; - algofile = tmpDir + algofile; - meshfile = tmpDir + meshfile; - - HDFfile *hdf_file; - map < int, HDFgroup * >hdf_group, hdf_subgroup; - map < int, HDFdataset * >hdf_dataset; - FILE *destFile; - - SALOMEDS::ChildIterator_var itBig, it, itSM; - SALOMEDS::SObject_var mySObject, myBranch, mySObjectChild; - hdf_size size[1]; - int longueur, cmpt_ds = 0, cmpt_it; - char *name_group, name_dataset[30], name_meshgroup[30]; - bool ok, _found; - int cmpt_sm = 0, myTag; - -//************* HDF file creation - hdf_file = new HDFfile(filename.ToCString()); - hdf_file->CreateOnDisk(); -//**************************** - - itBig = Study->NewChildIterator(theComponent); - SCRUTE(Tag_HypothesisRoot); - SCRUTE(Tag_AlgorithmsRoot); - for (; itBig->More(); itBig->Next()) - { - SALOMEDS::SObject_var gotBranch = itBig->Value(); - SCRUTE(gotBranch->Name()); - SCRUTE(gotBranch->Tag()); - SCRUTE(gotBranch->GetID()); - -//************branch 1 : hypothesis - if (gotBranch->Tag() == Tag_HypothesisRoot) - { //hypothesis = tag 1 - double length, maxElementsArea, maxElementsVolume; - int numberOfSegments; - - destFile = fopen(hypofile.ToCString(), "w"); - it = Study->NewChildIterator(gotBranch); - for (; it->More(); it->Next()) - { - mySObject = it->Value(); - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::AttributeIOR_var anIOR; - if (mySObject->FindAttribute(anAttr, "AttributeIOR")) - { - anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - - SMESH::SMESH_Hypothesis_var myHyp = - SMESH::SMESH_Hypothesis::_narrow(_orb-> - string_to_object(anIOR->Value())); - SCRUTE(myHyp->GetName()); - fprintf(destFile, "%li\n", myHyp->GetId()); - fprintf(destFile, "%s\n", myHyp->GetName()); - if (strcmp(myHyp->GetName(), "LocalLength") == 0) - { - SMESH::SMESH_LocalLength_var LL = - SMESH::SMESH_LocalLength::_narrow(myHyp); - length = LL->GetLength(); - fprintf(destFile, "%f\n", length); - } - else if (strcmp(myHyp->GetName(), "NumberOfSegments") == 0) - { - SMESH::SMESH_NumberOfSegments_var NOS = - SMESH::SMESH_NumberOfSegments::_narrow(myHyp); - numberOfSegments = NOS->GetNumberOfSegments(); - fprintf(destFile, "%d\n", numberOfSegments); - } - else if (strcmp(myHyp->GetName(), "MaxElementArea") == 0) - { - SMESH::SMESH_MaxElementArea_var MEA = - SMESH::SMESH_MaxElementArea::_narrow(myHyp); - maxElementsArea = MEA->GetMaxElementArea(); - fprintf(destFile, "%f\n", maxElementsArea); - } - else if (strcmp(myHyp->GetName(), "MaxElementVolume") == 0) - { - SMESH::SMESH_MaxElementVolume_var MEV = - SMESH::SMESH_MaxElementVolume::_narrow(myHyp); - maxElementsVolume = MEV->GetMaxElementVolume(); - fprintf(destFile, "%f\n", maxElementsVolume); - } - } - } - fclose(destFile); - -//writes the file name in the hdf file - longueur = hypofile.Length() + 1; - name_group = "Hypothesis"; - //SCRUTE(name_group); - - size[0] = longueur; - hdf_group[1] = new HDFgroup(name_group, hdf_file); - hdf_group[1]->CreateOnDisk(); - - hdf_dataset[cmpt_ds] = - new HDFdataset(name_group, hdf_group[1], HDF_STRING, size, 1); - hdf_dataset[cmpt_ds]->CreateOnDisk(); - hdf_dataset[cmpt_ds]->WriteOnDisk(hypofile.ToCString()); - hdf_dataset[cmpt_ds]->CloseOnDisk(); - cmpt_ds++; - - hdf_group[1]->CloseOnDisk(); - MESSAGE("End of Hypothesis Save"); - - } -//************branch 2 : algorithms - else if (gotBranch->Tag() == Tag_AlgorithmsRoot) - { //algos = tag 2 - destFile = fopen(algofile.ToCString(), "w"); - it = Study->NewChildIterator(gotBranch); - for (; it->More(); it->Next()) - { - mySObject = it->Value(); - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::AttributeIOR_var anIOR; - if (mySObject->FindAttribute(anAttr, "AttributeIOR")) - { - anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - SMESH::SMESH_Algo_var myAlgo = - SMESH::SMESH_Algo::_narrow(_orb-> - string_to_object(anIOR->Value())); - SCRUTE(anIOR->Value()); - SCRUTE(myAlgo->_is_nil()); - fprintf(destFile, "%li\n", myAlgo->GetId()); - fprintf(destFile, "%s\n", myAlgo->GetName()); - } - } - - fclose(destFile); - -//writes the file name in the hdf file - longueur = algofile.Length() + 1; - name_group = "Algorithms"; - //SCRUTE(name_group); - - size[0] = longueur; - hdf_group[2] = new HDFgroup(name_group, hdf_file); - hdf_group[2]->CreateOnDisk(); - - hdf_dataset[cmpt_ds] = - new HDFdataset(name_group, hdf_group[2], HDF_STRING, size, 1); - hdf_dataset[cmpt_ds]->CreateOnDisk(); - hdf_dataset[cmpt_ds]->WriteOnDisk(algofile.ToCString()); - hdf_dataset[cmpt_ds]->CloseOnDisk(); - cmpt_ds++; - - hdf_group[2]->CloseOnDisk(); - MESSAGE("End of Algos Save"); - - } -//************branch 3 : meshes - else if (gotBranch->Tag() >= 3) - { //meshes = tag > 3 - - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::AttributeIOR_var anIOR; - if (gotBranch->FindAttribute(anAttr, "AttributeIOR")) - { - anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - - SMESH::SMESH_Mesh_var myMesh = - SMESH::SMESH_Mesh::_narrow(_orb->string_to_object(anIOR-> - Value())); - studyId = myMesh->GetStudyId(); - SCRUTE(studyId); - - StudyContext_iStruct *myStudyContext = - _mapStudyContext_i[studyId]; - int meshId = myMesh->GetId(); - SMESH_Mesh_i *meshServant = myStudyContext->mapMesh_i[meshId]; - ::SMESH_Mesh & myLocMesh = meshServant->GetImpl(); - SMESHDS_Mesh *mySMESHDSMesh = myLocMesh.GetMeshDS(); - - SCRUTE(mySMESHDSMesh->NbNodes()); - if (mySMESHDSMesh->NbNodes() > 0) - { - //checks if the mesh is not empty - Mesh_Writer *myWriter = SMESHDriver::GetMeshWriter("MED"); - myWriter->SetFile(meshfile.ToCString()); - myWriter->SetMesh(mySMESHDSMesh); - myWriter->SetMeshId(gotBranch->Tag()); - myWriter->Add(); - } - else - meshfile = "No data"; - - //********** opening of the HDF group - sprintf(name_meshgroup, "Mesh %d", meshId); - SCRUTE(name_meshgroup); - hdf_group[gotBranch->Tag()] = - new HDFgroup(name_meshgroup, hdf_file); - hdf_group[gotBranch->Tag()]->CreateOnDisk(); - //********** - - //********** file where the data are stored - longueur = strlen(meshfile.ToCString()) + 1; - size[0] = longueur; - strcpy(name_dataset, "Mesh data"); - hdf_dataset[cmpt_ds] = - new HDFdataset(name_dataset, hdf_group[gotBranch->Tag()], - HDF_STRING, size, 1); - hdf_dataset[cmpt_ds]->CreateOnDisk(); - hdf_dataset[cmpt_ds]->WriteOnDisk(meshfile.ToCString()); - hdf_dataset[cmpt_ds]->CloseOnDisk(); - cmpt_ds++; - //********** - - //********** ref on shape - Standard_CString myRefOnObject = ""; - SALOMEDS::SObject_var myRef, myShape; - _found = gotBranch->FindSubObject(Tag_RefOnShape, myRef); - if (_found) - { - ok = myRef->ReferencedObject(myShape); - myRefOnObject = myShape->GetID(); - SCRUTE(myRefOnObject); - - longueur = strlen(myRefOnObject) + 1; - if (longueur > 1) - { - size[0] = longueur; - strcpy(name_dataset, "Ref on shape"); - hdf_dataset[cmpt_ds] = - new HDFdataset(name_dataset, - hdf_group[gotBranch->Tag()], HDF_STRING, size, 1); - hdf_dataset[cmpt_ds]->CreateOnDisk(); - hdf_dataset[cmpt_ds]->WriteOnDisk(myRefOnObject); - hdf_dataset[cmpt_ds]->CloseOnDisk(); - cmpt_ds++; - - } - } - //********** - - //********** ref on applied hypothesis - _found = - gotBranch->FindSubObject(Tag_RefOnAppliedHypothesis, - myBranch); - if (_found) - { - - strcpy(name_meshgroup, "Applied Hypothesis"); - hdf_subgroup[Tag_RefOnAppliedHypothesis] = - new HDFgroup(name_meshgroup, - hdf_group[gotBranch->Tag()]); - hdf_subgroup[Tag_RefOnAppliedHypothesis]->CreateOnDisk(); - - it = Study->NewChildIterator(myBranch); - cmpt_it = 0; - for (; it->More(); it->Next()) - { - mySObject = it->Value(); - ok = mySObject->ReferencedObject(myRef); - myRefOnObject = myRef->GetID(); - - longueur = strlen(myRefOnObject) + 1; - if (longueur > 1) - { - size[0] = longueur; - sprintf(name_dataset, "Hyp %d", cmpt_it); - hdf_dataset[cmpt_ds] = - new HDFdataset(name_dataset, - hdf_subgroup[Tag_RefOnAppliedHypothesis], - HDF_STRING, size, 1); - hdf_dataset[cmpt_ds]->CreateOnDisk(); - hdf_dataset[cmpt_ds]->WriteOnDisk(myRefOnObject); - hdf_dataset[cmpt_ds]->CloseOnDisk(); - } - cmpt_ds++; - cmpt_it++; - } - hdf_subgroup[Tag_RefOnAppliedHypothesis]->CloseOnDisk(); - } - //********** - - //********** ref on applied algorithms - _found = - gotBranch->FindSubObject(Tag_RefOnAppliedAlgorithms, - myBranch); - if (_found) - { - - strcpy(name_meshgroup, "Applied Algorithms"); - hdf_subgroup[Tag_RefOnAppliedAlgorithms] = - new HDFgroup(name_meshgroup, - hdf_group[gotBranch->Tag()]); - hdf_subgroup[Tag_RefOnAppliedAlgorithms]->CreateOnDisk(); - - it = Study->NewChildIterator(myBranch); - cmpt_it = 0; - for (; it->More(); it->Next()) - { - mySObject = it->Value(); - ok = mySObject->ReferencedObject(myRef); - myRefOnObject = myRef->GetID(); - - longueur = strlen(myRefOnObject) + 1; - if (longueur > 1) - { - size[0] = longueur; - sprintf(name_dataset, "Algo %d", cmpt_it); - hdf_dataset[cmpt_ds] = - new HDFdataset(name_dataset, - hdf_subgroup[Tag_RefOnAppliedAlgorithms], - HDF_STRING, size, 1); - hdf_dataset[cmpt_ds]->CreateOnDisk(); - hdf_dataset[cmpt_ds]->WriteOnDisk(myRefOnObject); - hdf_dataset[cmpt_ds]->CloseOnDisk(); - } - cmpt_ds++; - cmpt_it++; - } - hdf_subgroup[Tag_RefOnAppliedAlgorithms]->CloseOnDisk(); - } - MESSAGE("end of algo applied"); - //********** - - //********** submeshes on subshapes - int myLevel1Tag; - for (int i = Tag_SubMeshOnVertex; i <= Tag_SubMeshOnCompound; - i++) - { - _found = gotBranch->FindSubObject(i, myBranch); - if (_found) - { - if (i == Tag_SubMeshOnVertex) - strcpy(name_meshgroup, "SubMeshes On Vertex"); - else if (i == Tag_SubMeshOnEdge) - strcpy(name_meshgroup, "SubMeshes On Edge"); - else if (i == Tag_SubMeshOnFace) - strcpy(name_meshgroup, "SubMeshes On Face"); - else if (i == Tag_SubMeshOnSolid) - strcpy(name_meshgroup, "SubMeshes On Solid"); - else if (i == Tag_SubMeshOnCompound) - strcpy(name_meshgroup, "SubMeshes On Compound"); - - cmpt_sm++; - myLevel1Tag = 10 + cmpt_sm; - hdf_subgroup[myLevel1Tag] = - new HDFgroup(name_meshgroup, - hdf_group[gotBranch->Tag()]); - hdf_subgroup[myLevel1Tag]->CreateOnDisk(); - - itSM = Study->NewChildIterator(myBranch); - for (; itSM->More(); itSM->Next()) - { //Loop on all submeshes - mySObject = itSM->Value(); - cmpt_sm++; - myTag = 10 + cmpt_sm; - mySObject->FindAttribute(anAttr, "AttributeIOR"); - anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - SMESH::SMESH_subMesh_var mySubMesh = - SMESH::SMESH_subMesh::_narrow(_orb-> - string_to_object(anIOR->Value())); - - //sprintf(name_meshgroup,"SubMesh %d",myTag); - sprintf(name_meshgroup, "SubMesh %ld", - mySubMesh->GetId()); - SCRUTE(name_meshgroup); - - hdf_subgroup[myTag] = - new HDFgroup(name_meshgroup, - hdf_subgroup[myLevel1Tag]); - hdf_subgroup[myTag]->CreateOnDisk(); - - //********** ref on shape - Standard_CString myRefOnObject = ""; - SALOMEDS::SObject_var myRef, myShape; - bool _found2; - _found2 = - mySObject->FindSubObject(Tag_RefOnShape, myRef); - if (_found2) - { - ok = myRef->ReferencedObject(myShape); - myRefOnObject = myShape->GetID(); - SCRUTE(myRefOnObject); - - longueur = strlen(myRefOnObject) + 1; - if (longueur > 1) - { - size[0] = longueur; - strcpy(name_dataset, "Ref on shape"); - hdf_dataset[cmpt_ds] = - new HDFdataset(name_dataset, - hdf_subgroup[myTag], HDF_STRING, size, - 1); - hdf_dataset[cmpt_ds]->CreateOnDisk(); - hdf_dataset[cmpt_ds]-> - WriteOnDisk(myRefOnObject); - hdf_dataset[cmpt_ds]->CloseOnDisk(); - cmpt_ds++; - } - } - //********** - - //********** ref on applied hypothesis - _found2 = - mySObject-> - FindSubObject(Tag_RefOnAppliedHypothesis, - myBranch); - if (_found2) - { - - strcpy(name_meshgroup, "Applied Hypothesis"); - cmpt_sm++; - hdf_subgroup[10 + cmpt_sm] = - new HDFgroup(name_meshgroup, - hdf_subgroup[myTag]); - hdf_subgroup[10 + cmpt_sm]->CreateOnDisk(); - - it = Study->NewChildIterator(myBranch); - cmpt_it = 0; - for (; it->More(); it->Next()) - { - mySObjectChild = it->Value(); - ok = mySObjectChild-> - ReferencedObject(myRef); - myRefOnObject = myRef->GetID(); - - longueur = strlen(myRefOnObject) + 1; - if (longueur > 1) - { - size[0] = longueur; - sprintf(name_dataset, "Hyp %d", - cmpt_it); - SCRUTE(cmpt_it); - hdf_dataset[cmpt_ds] = - new HDFdataset(name_dataset, - hdf_subgroup[10 + cmpt_sm], - HDF_STRING, size, 1); - hdf_dataset[cmpt_ds]->CreateOnDisk(); - hdf_dataset[cmpt_ds]-> - WriteOnDisk(myRefOnObject); - hdf_dataset[cmpt_ds]->CloseOnDisk(); - } - cmpt_ds++; - cmpt_it++; - } - hdf_subgroup[10 + cmpt_sm]->CloseOnDisk(); - } - //********** - - //********** ref on applied algorithms - _found2 = - mySObject-> - FindSubObject(Tag_RefOnAppliedAlgorithms, - myBranch); - SCRUTE(_found2); - if (_found2) - { - - strcpy(name_meshgroup, "Applied Algorithms"); - cmpt_sm++; - hdf_subgroup[10 + cmpt_sm] = - new HDFgroup(name_meshgroup, - hdf_subgroup[myTag]); - hdf_subgroup[10 + cmpt_sm]->CreateOnDisk(); - - it = Study->NewChildIterator(myBranch); - cmpt_it = 0; - for (; it->More(); it->Next()) - { - mySObjectChild = it->Value(); - ok = mySObjectChild-> - ReferencedObject(myRef); - myRefOnObject = myRef->GetID(); - - longueur = strlen(myRefOnObject) + 1; - if (longueur > 1) - { - size[0] = longueur; - sprintf(name_dataset, "Algo %d", - cmpt_it); - hdf_dataset[cmpt_ds] = - new HDFdataset(name_dataset, - hdf_subgroup[10 + cmpt_sm], - HDF_STRING, size, 1); - hdf_dataset[cmpt_ds]->CreateOnDisk(); - hdf_dataset[cmpt_ds]-> - WriteOnDisk(myRefOnObject); - hdf_dataset[cmpt_ds]->CloseOnDisk(); - } - cmpt_ds++; - cmpt_it++; - } - hdf_subgroup[10 + cmpt_sm]->CloseOnDisk(); - } - //MESSAGE("end of algo applied"); - //********** - - hdf_subgroup[myTag]->CloseOnDisk(); - } - - hdf_subgroup[myLevel1Tag]->CloseOnDisk(); - } - - } - //********** - - //********** closing of the HDF group - hdf_group[gotBranch->Tag()]->CloseOnDisk(); - MESSAGE("End of Mesh Save"); - //********** - } - } - MESSAGE("End of Meshes Save"); - } - - MESSAGE("hdf_file->CloseOnDisk()"); - hdf_file->CloseOnDisk(); - - MESSAGE("delete hdf_file"); - delete hdf_file; - hdf_file = 0; + MESSAGE( "SMESH_Gen_i::SMESH_Gen_i : default constructor" ); +} - // Convert temporary files to stream - MESSAGE("Convert temporary files to stream"); - aStreamFile = - SALOMEDS_Tool::PutFilesToStream(tmpDir.ToCString(), aFileSeq.in(), - isMultiFile); +//============================================================================= +/*! + * SMESH_Gen_i::SMESH_Gen_i + * + * Standard constructor, used with Container + */ +//============================================================================= - // Remove temporary files and directory - MESSAGE("Remove temporary files and directory"); - if (!isMultiFile) - SALOMEDS_Tool::RemoveTemporaryFiles(tmpDir.ToCString(), aFileSeq.in(), - true); +SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + PortableServer::ObjectId* contId, + const char* instanceName, + const char* interfaceName ) + : Engines_Component_i( orb, poa, contId, instanceName, interfaceName ) +{ + MESSAGE( "SMESH_Gen_i::SMESH_Gen_i : standard constructor" ); + + myOrb = CORBA::ORB::_duplicate(orb); + myPoa = PortableServer::POA::_duplicate(poa); + + _thisObj = this ; + _id = myPoa->activate_object( _thisObj ); + + myShapeReader = NULL; // shape reader +} - MESSAGE("End SMESH_Gen_i::Save"); +//============================================================================= +/*! + * SMESH_Gen_i::~SMESH_Gen_i + * + * Destructor + */ +//============================================================================= - return aStreamFile._retn(); +SMESH_Gen_i::~SMESH_Gen_i() +{ + MESSAGE( "SMESH_Gen_i::~SMESH_Gen_i" ); + + // delete hypothesis creators + map::iterator itHyp; + for (itHyp = myHypCreatorMap.begin(); itHyp != myHypCreatorMap.end(); itHyp++) + { + delete (*itHyp).second; + } + myHypCreatorMap.clear(); + + // Clear study contexts data + map::iterator it; + for ( it = myStudyContextMap.begin(); it != myStudyContextMap.end(); ++it ) { + delete it->second; + } + myStudyContextMap.clear(); + // delete shape reader + if ( !myShapeReader ) + delete myShapeReader; } + +//============================================================================= +/*! + * SMESH_Gen_i::CreateFilterManager + * + * Create filter manager + */ +//============================================================================= -SALOMEDS::TMPFile * - SMESH_Gen_i::SaveASCII(SALOMEDS::SComponent_ptr theComponent, - const char *theURL, bool isMultiFile) +SMESH::FilterManager_ptr SMESH_Gen_i::CreateFilterManager() { - SALOMEDS::TMPFile_var aStreamFile = Save(theComponent, theURL, isMultiFile); - return aStreamFile._retn(); + SMESH::FilterManager_i* aFilter = new SMESH::FilterManager_i(); + SMESH::FilterManager_var anObj = aFilter->_this(); + return anObj._retn(); } -void SMESH_Gen_i::loadHypothesis(char * name, HDFfile * hdf_file, - char * hypofile, int studyId) +//============================================================================= +/*! + * SMESH_Gen_i::createHypothesis + * + * Create hypothesis of given type + */ +//============================================================================= +SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName, + const char* theLibName) + throw (SALOME::SALOME_Exception) { - char name_of_group[HDF_NAME_MAX_LEN + 1]; - char objectId[10]; - - HDFgroup * hdfGroup = new HDFgroup(name, hdf_file); - hdfGroup->OpenOnDisk(); - - hdfGroup->InternalObjectIndentify(0, name_of_group); - HDFdataset * dataset = new HDFdataset(name_of_group, hdfGroup); - dataset->OpenOnDisk(); - char *name_of_file = new char[dataset->GetSize()]; - dataset->ReadFromDisk(name_of_file); - SCRUTE(name_of_file); - dataset->CloseOnDisk(); - hdfGroup->CloseOnDisk(); - delete[]name_of_file; - - ifstream loadedFile(hypofile); - while (!loadedFile.eof()) - { - int hypothesisID; - string hypothesisName; - loadedFile >> hypothesisID; - loadedFile >> hypothesisName; - if(hypothesisName.length()==0) break; - SMESH_Hypothesis_i * corbaHyp = - _hypothesisFactory_i.Create(hypothesisName.c_str(), studyId, &_impl); - SMESH_Hypothesis * localHyp = corbaHyp->getImpl(); - localHyp->SetID(hypothesisID); - localHyp->LoadFrom(loadedFile); - - SMESH::SMESH_Hypothesis_var varHyp = corbaHyp->_this(); - string iorString = _orb->object_to_string(varHyp); - sprintf(objectId, "%ld", varHyp->GetId()); - _SMESHCorbaObj[string("Hypo_") + string(objectId)] = - iorString; - } - MESSAGE("End of Hypos Load"); + Unexpect aCatch(SALOME_SalomeException); + MESSAGE( "Create Hypothesis <" << theHypName << "> from " << theLibName); + + // get study context + StudyContext* myStudyContext = GetCurrentStudyContext(); + + // create a new hypothesis object servant + SMESH_Hypothesis_i* myHypothesis_i = 0; + SMESH::SMESH_Hypothesis_var hypothesis_i; + + try + { + // check, if creator for this hypothesis type already exists + if (myHypCreatorMap.find(string(theHypName)) == myHypCreatorMap.end()) + { + // load plugin library + MESSAGE("Loading server meshers plugin library ..."); + void* libHandle = dlopen (theLibName, RTLD_LAZY); + if (!libHandle) + { + // report any error, if occured + const char* anError = dlerror(); + throw(SALOME_Exception(anError)); + } + + // get method, returning hypothesis creator + MESSAGE("Find GetHypothesisCreator() method ..."); + typedef GenericHypothesisCreator_i* (*GetHypothesisCreator)(const char* theHypName); + GetHypothesisCreator procHandle = + (GetHypothesisCreator)dlsym( libHandle, "GetHypothesisCreator" ); + if (!procHandle) + { + throw(SALOME_Exception(LOCALIZED("bad hypothesis plugin library"))); + dlclose(libHandle); + } + + // get hypothesis creator + MESSAGE("Get Hypothesis Creator for " << theHypName); + GenericHypothesisCreator_i* aCreator = procHandle(theHypName); + if (!aCreator) + { + throw(SALOME_Exception(LOCALIZED("no such a hypothesis in this plugin"))); + } + + // map hypothesis creator to a hypothesis name + myHypCreatorMap[string(theHypName)] = aCreator; + } + + // create a new hypothesis object, store its ref. in studyContext + MESSAGE("Create Hypothesis " << theHypName); + myHypothesis_i = + myHypCreatorMap[string(theHypName)]->Create + (myPoa, myCurrentStudy->StudyId(), &myGen); + myHypothesis_i->SetLibName(theLibName); // for persistency assurance + } + catch (SALOME_Exception& S_ex) + { + THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); + } + + if (!myHypothesis_i) + return hypothesis_i._retn(); + + // activate the CORBA servant of hypothesis + hypothesis_i = SMESH::SMESH_Hypothesis::_narrow( myHypothesis_i->_this() ); + string iorString = GetORB()->object_to_string( hypothesis_i ); + int nextId = myStudyContext->addObject( iorString ); + MESSAGE( "Add hypo to map with id = "<< nextId << " and IOR = " << iorString.c_str() ); + + return hypothesis_i._retn(); } - -void SMESH_Gen_i::loadAlgorithms(char * name, HDFfile * hdf_file, - char* algofile, int studyId) + +//============================================================================= +/*! + * SMESH_Gen_i::createMesh + * + * Create empty mesh on shape + */ +//============================================================================= +SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh() + throw ( SALOME::SALOME_Exception ) { - char name_of_group[HDF_NAME_MAX_LEN + 1]; - char objectId[10]; - HDFgroup * hdfGroup = new HDFgroup(name, hdf_file); - hdfGroup->OpenOnDisk(); - - hdfGroup->InternalObjectIndentify(0, name_of_group); - HDFdataset * dataset = - new HDFdataset(name_of_group, hdfGroup); - dataset->OpenOnDisk(); - - char *name_of_file = new char[dataset->GetSize()]; - dataset->ReadFromDisk(name_of_file); - dataset->CloseOnDisk(); - hdfGroup->CloseOnDisk(); - delete[]name_of_file; - - char * aLine = new char[100]; - FILE * loadedFile = fopen(algofile, "r"); - while (!feof(loadedFile)) - { - int hypothesisID; - fscanf(loadedFile, "%i", &hypothesisID); - fscanf(loadedFile, "%s\n", aLine); - //SCRUTE(aLine); - if (strcmp(aLine, "") != 0) - { - SMESH_Hypothesis_i * corbaHyp = - _hypothesisFactory_i.Create(aLine, studyId, &_impl); - SMESH_Hypothesis * localHyp = corbaHyp->getImpl(); - localHyp->SetID(hypothesisID); - - SMESH::SMESH_Hypothesis_var myHyp = corbaHyp->_this(); - - SMESH::SMESH_Algo_var myAlgo = - SMESH::SMESH_Algo::_narrow(myHyp); - string iorString = _orb->object_to_string(myAlgo); - sprintf(objectId, "%ld", myAlgo->GetId()); - _SMESHCorbaObj[string("Hypo_") + string(objectId)] = - iorString; - } - } - fclose(loadedFile); - delete[]aLine; - aLine = 0; - MESSAGE("End of Algos Load"); + Unexpect aCatch(SALOME_SalomeException); + MESSAGE( "SMESH_Gen_i::createMesh" ); + + // get current study + StudyContext* myStudyContext = GetCurrentStudyContext(); + + // Get or create the GEOM_Client instance + try { + // create a new mesh object servant, store it in a map in study context + SMESH_Mesh_i* meshServant = new SMESH_Mesh_i( GetPOA(), + this, + myCurrentStudy->StudyId() ); + // create a new mesh object + meshServant->SetImpl( myGen.CreateMesh( myCurrentStudy->StudyId() ) ); + + // activate the CORBA servant of Mesh + SMESH::SMESH_Mesh_var mesh = meshServant->_this(); + string iorString = GetORB()->object_to_string( mesh ); + int nextId = myStudyContext->addObject( iorString ); + MESSAGE( "Add mesh to map with id = "<< nextId << " and IOR = " << iorString.c_str() ); + return mesh._retn(); + } + catch (SALOME_Exception& S_ex) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM ); + } + return SMESH::SMESH_Mesh::_nil(); } -/** - * @param hdfGroupMeshId The group where to read the hypothesis - * @param _found ??? - * @param Study The study where to create the hypothesis - * @param myNewMesh The mesh on which the hypothesis is applied - * @param aShape The shape with which this mesh is linked +//============================================================================= +/*! + * SMESH_Gen_i::GetShapeReader + * + * Get shape reader */ -void SMESH_Gen_i::loadAppliedHypothesis(HDFgroup * hdfGroupMeshId, - bool _found, SALOMEDS::Study_var Study, SMESH::SMESH_Mesh_var myNewMesh, - GEOM::GEOM_Shape_var aShape) +//============================================================================= +GEOM_Client* SMESH_Gen_i::GetShapeReader() { - HDFgroup * hdf_subgroup = new HDFgroup("Applied Hypothesis", hdfGroupMeshId); - hdf_subgroup->OpenOnDisk(); - int nb_datasets = hdf_subgroup->nInternalObjects(); - char name_dataset[10]; - - for (int j = 0; j < nb_datasets; j++) - { - sprintf(name_dataset, "Hyp %d", j); - HDFdataset * hdf_dataset = new HDFdataset(name_dataset, hdf_subgroup); - hdf_dataset->OpenOnDisk(); - - char *refFromFile = new char[hdf_dataset->GetSize()]; - hdf_dataset->ReadFromDisk(refFromFile); - hdf_dataset->CloseOnDisk(); - delete hdf_dataset; - - if (_found) - { - SALOMEDS::SObject_var HypSO = - Study->FindObjectID(refFromFile); - if (!CORBA::is_nil(HypSO)) - { - SALOMEDS::GenericAttribute_var anAttr; - HypSO->FindAttribute(anAttr, "AttributeIOR"); - SALOMEDS::AttributeIOR_var anIOR = - SALOMEDS::AttributeIOR::_narrow(anAttr); - if (!CORBA::is_nil(anIOR)) - { - char *HypIOR = anIOR->Value(); - SMESH::SMESH_Hypothesis_var anHyp = - SMESH::SMESH_Hypothesis::_narrow(_orb-> - string_to_object(HypIOR)); - if (!CORBA::is_nil(anHyp)) - { - myNewMesh->AddHypothesis(aShape, anHyp); - MESSAGE("Hypothesis added ..."); - } - } - } - } - } - hdf_subgroup->CloseOnDisk(); + // create shape reader if necessary + if ( !myShapeReader ) + myShapeReader = new GEOM_Client(GetContainerRef()); + ASSERT( myShapeReader ); + return myShapeReader; } -/** - * @param hdfGroupMeshId The group where to read the hypothesis - * @param _found ??? - * @param Study The study where to create the hypothesis - * @param myNewMesh The mesh on which the hypothesis is applied - * @param aShape The shape with which this mesh is linked +//============================================================================= +/*! + * SMESH_Gen_i::SetCurrentStudy + * + * Set current study */ -void SMESH_Gen_i::loadAppliedAlgorithms(HDFgroup * hdfGroupMeshId, - bool _found, SALOMEDS::Study_var Study, SMESH::SMESH_Mesh_var myNewMesh, - GEOM::GEOM_Shape_var aShape) -{ - HDFgroup * hdf_subgroup = new HDFgroup("Applied Algorithms", hdfGroupMeshId); - hdf_subgroup->OpenOnDisk(); +//============================================================================= - int nb_datasets = hdf_subgroup->nInternalObjects(); - SCRUTE(nb_datasets); - char name_dataset[10]; - - for (int j = 0; j < nb_datasets; j++) - { - sprintf(name_dataset, "Algo %d", j); - HDFdataset * dataset = - new HDFdataset(name_dataset, hdf_subgroup); - dataset->OpenOnDisk(); - - char *refFromFile = new char[dataset->GetSize()]; - dataset->ReadFromDisk(refFromFile); - dataset->CloseOnDisk(); - - if (_found) - { - SALOMEDS::SObject_var AlgoSO = - Study->FindObjectID(refFromFile); - if (!CORBA::is_nil(AlgoSO)) - { - SALOMEDS::GenericAttribute_var anAttr; - AlgoSO->FindAttribute(anAttr, "AttributeIOR"); - SALOMEDS::AttributeIOR_var anIOR = - SALOMEDS::AttributeIOR::_narrow(anAttr); - if (!CORBA::is_nil(anIOR)) - { - char *AlgoIOR = anIOR->Value(); - //SCRUTE(AlgoIOR); - SMESH::SMESH_Hypothesis_var myHyp = - SMESH::SMESH_Hypothesis::_narrow(_orb-> - string_to_object(AlgoIOR)); - SMESH::SMESH_Algo_var anAlgo = - SMESH::SMESH_Algo::_narrow(myHyp); - - if (!CORBA::is_nil(anAlgo)) - { - myNewMesh->AddHypothesis(aShape, anAlgo); //essayer avec _SMESHCorbaObj - MESSAGE("Algorithms added ..."); - } - } - } - } - } - hdf_subgroup->CloseOnDisk(); +void SMESH_Gen_i::SetCurrentStudy( SALOMEDS::Study_ptr theStudy ) +{ + MESSAGE( "SMESH_Gen_i::SetCurrentStudy" ); + myCurrentStudy = SALOMEDS::Study::_duplicate( theStudy ); + // create study context, if it doesn't exist and set current study + int studyId = myCurrentStudy->StudyId(); + MESSAGE( "SMESH_Gen_i::SetCurrentStudy: study Id = " << studyId ); + if ( myStudyContextMap.find( studyId ) == myStudyContextMap.end() ) { + myStudyContextMap[ studyId ] = new StudyContext; + } + // set current study for geom engine + if ( !CORBA::is_nil( GetGeomEngine() ) ) + GetGeomEngine()->GetCurrentStudy( myCurrentStudy->StudyId() ); } -/** - * @param hdfGroupMeshId The group where to read the hypothesis - * @param msgname ??? - * @param Study The study where to create the hypothesis - * @param myNewMesh The mesh on which the hypothesis is applied +//============================================================================= +/*! + * SMESH_Gen_i::GetCurrentStudy + * + * Get current study */ -void SMESH_Gen_i::loadSubMeshes(HDFgroup * hdfGroupMeshId, char * msgname, - SALOMEDS::Study_var Study, SMESH::SMESH_Mesh_var myNewMesh) +//============================================================================= + +SALOMEDS::Study_ptr SMESH_Gen_i::GetCurrentStudy() { - MESSAGE("SMESH_Gen_i::loadSubMeshes"); - HDFgroup * hdf_subgroupmyLevel1Tag = new HDFgroup(msgname, hdfGroupMeshId); - hdf_subgroupmyLevel1Tag->OpenOnDisk(); + MESSAGE( "SMESH_Gen_i::GetCurrentStudy: study Id = " << myCurrentStudy->StudyId() ); + return SALOMEDS::Study::_duplicate( myCurrentStudy ); +} - int nb_submeshes = hdf_subgroupmyLevel1Tag->nInternalObjects(); - char name_meshgroup[30]; - //SCRUTE(nb_submeshes); +//============================================================================= +/*! + * SMESH_Gen_i::GetCurrentStudyContext + * + * Get current study context + */ +//============================================================================= +StudyContext* SMESH_Gen_i::GetCurrentStudyContext() +{ + ASSERT( !CORBA::is_nil( myCurrentStudy ) ) + ASSERT( myStudyContextMap.find( myCurrentStudy->StudyId() ) != myStudyContextMap.end() ); + return myStudyContextMap[ myCurrentStudy->StudyId() ]; +} - for (int j = 0; j < nb_submeshes; j++) - { - //cmpt_sm++; - //myTag = 10 + cmpt_sm; - hdf_subgroupmyLevel1Tag->InternalObjectIndentify(j, name_meshgroup); - - HDFgroup * hdf_subgroupmyTag = new HDFgroup(name_meshgroup, - hdf_subgroupmyLevel1Tag); - hdf_subgroupmyTag->OpenOnDisk(); - int subMeshId = atoi((string(name_meshgroup).substr(8, 18)).c_str()); - - MESSAGE("Ref on shape"); - //********** ref on shape - HDFdataset * hdf_dataset = - new HDFdataset("Ref on shape", hdf_subgroupmyTag); - hdf_dataset->OpenOnDisk(); - - char *refFromFile = new char[hdf_dataset->GetSize()]; - hdf_dataset->ReadFromDisk(refFromFile); - hdf_dataset->CloseOnDisk(); - - bool _found3 = false; - SALOMEDS::SObject_var GSO = Study->FindObjectID(refFromFile); - SMESH::SMESH_subMesh_var aSubMesh; - GEOM::GEOM_Shape_var aSubShape; - - if (!CORBA::is_nil(GSO)) - { - SALOMEDS::GenericAttribute_var anAttr; - GSO->FindAttribute(anAttr, "AttributeIOR"); - SALOMEDS::AttributeIOR_var anIOR = - SALOMEDS::AttributeIOR::_narrow(anAttr); - - char *SubShapeIOR = anIOR->Value(); - aSubShape = - GEOM::GEOM_Shape::_narrow(_orb-> string_to_object(SubShapeIOR)); - - if (!CORBA::is_nil(aSubShape)) - { - aSubMesh = myNewMesh->GetElementsOnShape(aSubShape); - string iorString = _orb->object_to_string(aSubMesh); - char objectId[10]; - sprintf(objectId, "%d", subMeshId); - _SMESHCorbaObj[string("SubMesh_") + string(objectId)] = - iorString; - _found3 = true; - } - } +//============================================================================= +/*! + * SMESH_Gen_i::CreateHypothesis + * + * Create hypothesis/algorothm of given type and publish it in the study + */ +//============================================================================= - int nb_subgroup = hdf_subgroupmyTag->nInternalObjects(); - SCRUTE(nb_subgroup); - char sgname[HDF_NAME_MAX_LEN + 1]; - for (int k = 0; k < nb_subgroup; k++) - { - hdf_subgroupmyTag->InternalObjectIndentify(k, sgname); - if (strcmp(sgname, "Ref on shape") == 0) - { - //nothing - } - else if (strcmp(sgname, "Applied Hypothesis") == 0) - { - //********** ref on applied hypothesis - MESSAGE("Applied Hypothesis"); - strcpy(name_meshgroup, "Applied Hypothesis"); - //cmpt_sm++; - HDFgroup * hdf_subgroup10cmpt_sm = new HDFgroup(name_meshgroup, - hdf_subgroupmyTag); - - hdf_subgroup10cmpt_sm->OpenOnDisk(); - int nb_datasets = hdf_subgroup10cmpt_sm->nInternalObjects(); - // SCRUTE(nb_datasets); - - char name_dataset[30]; - for (int l = 0; l < nb_datasets; l++) - { - sprintf(name_dataset, "Hyp %d", l); - HDFdataset * hdf_datasetcmpt_ds = - new HDFdataset(name_dataset, hdf_subgroup10cmpt_sm); - hdf_datasetcmpt_ds->OpenOnDisk(); - int size = hdf_datasetcmpt_ds->GetSize(); - - char *refFromFile = new char[size]; - hdf_datasetcmpt_ds->ReadFromDisk(refFromFile); - hdf_datasetcmpt_ds->CloseOnDisk(); - //cmpt_ds++; - - if (_found3) - { - SALOMEDS::SObject_var HypSO = - Study->FindObjectID(refFromFile); - if (!CORBA::is_nil(HypSO)) - { - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::AttributeIOR_var anIOR; - HypSO->FindAttribute(anAttr, "AttributeIOR"); - anIOR = SALOMEDS::AttributeIOR:: _narrow(anAttr); - if (!CORBA::is_nil(anIOR)) - { - char *HypIOR = anIOR->Value(); - SMESH::SMESH_Hypothesis_var anHyp = - SMESH::SMESH_Hypothesis::_narrow(_orb-> - string_to_object(HypIOR)); - if (!CORBA::is_nil(anHyp)) - { - SMESH::SMESH_Mesh_var aMesh = - aSubMesh->GetFather(); - aMesh->AddHypothesis(aSubShape, anHyp); //essayer avec _SMESHCorbaObj - MESSAGE("Hypothesis added ..."); - } - } - } - } - } - } - else if (strcmp(sgname, "Applied Algorithms") == 0) - { - //********** ref on applied algorithms - MESSAGE("Applied Algorithms"); - strcpy(name_meshgroup, "Applied Algorithms"); - //cmpt_sm++; - HDFgroup * hdf_subgroup10cmpt_sm = new HDFgroup(name_meshgroup, - hdf_subgroupmyTag); - hdf_subgroup10cmpt_sm->OpenOnDisk(); - int nb_datasets = hdf_subgroup10cmpt_sm->nInternalObjects(); - SCRUTE(nb_datasets); - - char name_dataset[30]; - for (int l = 0; l < nb_datasets; l++) - { - sprintf(name_dataset, "Algo %d", l); - HDFdataset * hdf_datasetcmpt_ds = new HDFdataset( - name_dataset, hdf_subgroup10cmpt_sm); - hdf_datasetcmpt_ds->OpenOnDisk(); - int size = hdf_datasetcmpt_ds->GetSize(); - - char *refFromFile = new char[size]; - hdf_datasetcmpt_ds->ReadFromDisk(refFromFile); - hdf_datasetcmpt_ds->CloseOnDisk(); - delete hdf_datasetcmpt_ds; - //cmpt_ds++; - - if (_found3) - { - SALOMEDS::SObject_var AlgoSO = - Study->FindObjectID(refFromFile); - if (!CORBA::is_nil(AlgoSO)) - { - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::AttributeIOR_var anIOR; - AlgoSO->FindAttribute(anAttr, "AttributeIOR"); - anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - if (!CORBA::is_nil(anIOR)) - { - char *AlgoIOR = anIOR->Value(); - //SCRUTE(AlgoIOR); - SMESH::SMESH_Hypothesis_var myHyp = - SMESH::SMESH_Hypothesis::_narrow(_orb-> - string_to_object(AlgoIOR)); - SMESH::SMESH_Algo_var anAlgo = - SMESH::SMESH_Algo::_narrow(myHyp); - //SMESH::SMESH_Algo_var anAlgo = SMESH::SMESH_Algo::_narrow(_orb->string_to_object(AlgoIOR)); - if (!CORBA::is_nil(anAlgo)) - { - SMESH::SMESH_Mesh_var aMesh = - aSubMesh->GetFather(); - aMesh->AddHypothesis(aSubShape, anAlgo); //essayer avec _SMESHCorbaObj - MESSAGE("Algorithms added ..."); - } - } - } - } - } - } - } - hdf_subgroupmyTag->CloseOnDisk(); - } - hdf_subgroupmyLevel1Tag->CloseOnDisk(); +SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::CreateHypothesis( const char* theHypName, + const char* theLibName ) + throw ( SALOME::SALOME_Exception ) +{ + Unexpect aCatch(SALOME_SalomeException); + ASSERT( !CORBA::is_nil( myCurrentStudy ) ); + // Create hypothesis/algorithm + SMESH::SMESH_Hypothesis_var hyp = this->createHypothesis( theHypName, theLibName ); + + // Publish hypothesis/algorithm in the study + if ( this->CanPublishInStudy( hyp ) ) { + this->PublishInStudy( myCurrentStudy, SALOMEDS::SObject::_nil(), hyp, "" ); + } + return hyp._retn(); } + +//============================================================================= +/*! + * SMESH_Gen_i::CreateMesh + * + * Create empty mesh on a shape and publish it in the study + */ +//============================================================================= -GEOM::GEOM_Gen_var SMESH_Gen_i::getGeomEngine() +SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMesh( GEOM::GEOM_Shape_ptr theShape ) + throw ( SALOME::SALOME_Exception ) { - MESSAGE("SMESH_Gen_i::getGeomEngine"); - SALOME_NamingService *_NS = SINGLETON_ < SALOME_NamingService >::Instance(); - ASSERT(SINGLETON_ < SALOME_NamingService >::IsAlreadyExisting()); - _NS->init_orb(_orb); - SALOME_LifeCycleCORBA *myEnginesLifeCycle = new SALOME_LifeCycleCORBA(_NS); - Engines::Component_var geomEngine = - myEnginesLifeCycle->FindOrLoad_Component("FactoryServer", "GEOM"); - GEOM::GEOM_Gen_var myGeomEngine = GEOM::GEOM_Gen::_narrow(geomEngine); - return myGeomEngine; + Unexpect aCatch(SALOME_SalomeException); + MESSAGE( "SMESH_Gen_i::CreateMesh" ); + ASSERT( !CORBA::is_nil( myCurrentStudy ) ); + // create mesh + SMESH::SMESH_Mesh_var mesh = this->createMesh(); + // publish mesh in the study + if ( this->CanPublishInStudy( mesh ) ) { + this->PublishInStudy( myCurrentStudy, SALOMEDS::SObject::_nil(), mesh.in(), "" ); + } + // set shape + SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( mesh ).in() ); + ASSERT( meshServant ); + meshServant->SetShape( theShape ); + return mesh._retn(); } + +//============================================================================= +/*! + * SMESH_Gen_i::CreateMeshFromMED + * + * Create mesh and import data from MED file + */ +//============================================================================= -GEOM::GEOM_Shape_var SMESH_Gen_i::getShape(SALOMEDS::Study_var Study, char * refFromFile) +SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName, + SMESH::DriverMED_ReadStatus& theStatus) + throw ( SALOME::SALOME_Exception ) { - MESSAGE("SMESH_Gen_i::getShape("<FindObjectID(refFromFile); - GEOM::GEOM_Shape_var aShape; + Unexpect aCatch(SALOME_SalomeException); + MESSAGE( "SMESH_Gen_i::CreateMeshFromMED" ); + ASSERT( !CORBA::is_nil( myCurrentStudy ) ); + + // Retrieve mesh names from the file + DriverMED_R_SMESHDS_Mesh myReader; + myReader.SetFile( theFileName ); + myReader.SetMeshId( -1 ); + list aNames = myReader.GetMeshNames(); + + SMESH::mesh_array_var aResult = new SMESH::mesh_array(); + aResult->length( aNames.size() ); + int i = 0; + + // Iterate through all meshes and create mesh objects + theStatus = SMESH::DRS_OK; + for ( list::iterator it = aNames.begin(); it != aNames.end(); it++ ) { + // create mesh + SMESH::SMESH_Mesh_var mesh = createMesh(); + + // publish mesh in the study + if ( CanPublishInStudy( mesh ) ) { + PublishInStudy( myCurrentStudy, SALOMEDS::SObject::_nil(), mesh.in(), (*it).c_str() ); + } + + // Read mesh data (groups are published automatically by ImportMEDFile()) + SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( mesh ).in() ); + ASSERT( meshServant ); + SMESH::DriverMED_ReadStatus status1 = + meshServant->ImportMEDFile( theFileName, (*it).c_str() ); + if (status1 > theStatus) + theStatus = status1; + + aResult[i++] = SMESH::SMESH_Mesh::_duplicate( mesh ); + } + + return aResult._retn(); +} - if (!CORBA::is_nil(CSO)) - { - SALOMEDS::GenericAttribute_var anAttr; - CSO->FindAttribute(anAttr, "AttributeIOR"); - if (!CORBA::is_nil(CSO)) - { - MESSAGE("The shape was not loaded. Try to load it."); - SALOMEDS::Driver_var driver = SALOMEDS::Driver::_narrow(getGeomEngine()); - SALOMEDS::SComponent_var SCO = SALOMEDS::SComponent::_narrow(Study->FindObject("Geometry")); - SALOMEDS::StudyBuilder_var B = Study->NewBuilder(); - B->LoadWith(SCO,driver); - CSO->FindAttribute(anAttr, "AttributeIOR"); - } +//============================================================================= +/*! + * SMESH_Gen_i::IsReadyToCompute + * + * Returns true if mesh contains enough data to be computed + */ +//============================================================================= - SALOMEDS::AttributeIOR_var anIOR = - SALOMEDS::AttributeIOR::_narrow(anAttr); - - char *ShapeIOR = anIOR->Value(); - aShape = - GEOM::GEOM_Shape::_narrow(_orb->string_to_object(ShapeIOR)); - } - return aShape; +CORBA::Boolean SMESH_Gen_i::IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh, + GEOM::GEOM_Shape_ptr theShape ) + throw ( SALOME::SALOME_Exception ) +{ + Unexpect aCatch(SALOME_SalomeException); + MESSAGE( "SMESH_Gen_i::IsReadyToCompute" ); + + if ( CORBA::is_nil( theShape ) ) + THROW_SALOME_CORBA_EXCEPTION( "bad shape reference", + SALOME::BAD_PARAM ); + + if ( CORBA::is_nil( theMesh ) ) + THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference", + SALOME::BAD_PARAM ); + + try { + // get mesh servant + SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( theMesh ).in() ); + ASSERT( meshServant ); + if ( meshServant ) { + // get local TopoDS_Shape + TopoDS_Shape myLocShape = GetShapeReader()->GetShape( GetGeomEngine(), theShape ); + // call implementation + ::SMESH_Mesh& myLocMesh = meshServant->GetImpl(); + return myGen.CheckAlgoState( myLocMesh, myLocShape ); + } + } + catch ( SALOME_Exception& S_ex ) { + MESSAGE( "catch exception "<< S_ex.what() ); + } + return false; } -void SMESH_Gen_i::loadMesh(char * name, HDFfile * hdf_file, - char* meshfile, SALOMEDS::Study_var Study) +//============================================================================= +/*! + * SMESH_Gen_i::GetSubShapesId + * + * Get sub-shapes unique ID's list + */ +//============================================================================= + +SMESH::long_array* SMESH_Gen_i::GetSubShapesId( GEOM::GEOM_Shape_ptr theMainShape, + const SMESH::shape_array& theListOfSubShape ) + throw ( SALOME::SALOME_Exception ) { - MESSAGE("SMESH_Gen_i::loadMesh("<OpenOnDisk(); - - int nb_meshsubgroup = hdfGroupMeshId->nInternalObjects(); - SCRUTE(nb_meshsubgroup); - - //********** Loading of the file name where the data are stored - strcpy(name_of_group, "Mesh data"); - HDFdataset * dataset = - new HDFdataset(name_of_group, hdfGroupMeshId); - dataset->OpenOnDisk(); - - char *datafilename = new char[dataset->GetSize()]; - dataset->ReadFromDisk(datafilename); - dataset->CloseOnDisk(); - MESSAGE("datafilename="<OpenOnDisk(); - - char *refFromFile = new char[dataset->GetSize()]; - dataset->ReadFromDisk(refFromFile); - dataset->CloseOnDisk(); + SMESH::long_array_var shapesId = new SMESH::long_array; + set setId; - bool _found = false; - SCRUTE(refFromFile); - SMESH::SMESH_Mesh_var myNewMesh; - GEOM::GEOM_Shape_var aShape=getShape(Study, refFromFile); + if ( CORBA::is_nil( theMainShape ) ) + THROW_SALOME_CORBA_EXCEPTION( "bad shape reference", + SALOME::BAD_PARAM ); - if (!CORBA::is_nil(aShape)) - { - _found = true; - myNewMesh = Init(getGeomEngine(), Study->StudyId(), aShape, myMeshId); - string iorString = _orb->object_to_string(myNewMesh); - sprintf(objectId, "%ld", myNewMesh->GetId()); - string key=string("Mesh_")+string(objectId); - MESSAGE("IOR of "<GetShape(GetGeomEngine(),theMainShape); + TopTools_IndexedMapOfShape myIndexToShape; + TopExp::MapShapes(myMainShape,myIndexToShape); - - //********** - //********** Loading of mesh data - if (strcmp(datafilename, "No data") != 0) - { - StudyContext_iStruct *myStudyContext = - _mapStudyContext_i[Study->StudyId()]; - int meshId = myNewMesh->GetId(); - SMESH_Mesh_i *meshServant = - myStudyContext->mapMesh_i[meshId]; - ::SMESH_Mesh & myLocMesh = meshServant->GetImpl(); - SMESHDS_Mesh *mySMESHDSMesh = myLocMesh.GetMeshDS(); - - Mesh_Reader *myReader = SMESHDriver::GetMeshReader("MED"); - myReader->SetMesh(mySMESHDSMesh); - myReader->SetMeshId(myMeshId); - myReader->SetFile(datafilename); - myReader->Read(); - mySMESHDSMesh->logFullUpdate(); - MESSAGE("Loaded a mesh with " << mySMESHDSMesh->NbNodes() <<" nodes"); - } + for (int i=0; iGetShape(GetGeomEngine(),aShape); + for (TopExp_Explorer exp(locShape,TopAbs_FACE); exp.More(); exp.Next()) + { + const TopoDS_Face& F = TopoDS::Face(exp.Current()); + setId.insert(myIndexToShape.FindIndex(F)); + SCRUTE(myIndexToShape.FindIndex(F)); + } + for (TopExp_Explorer exp(locShape,TopAbs_EDGE); exp.More(); exp.Next()) + { + const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); + setId.insert(myIndexToShape.FindIndex(E)); + SCRUTE(myIndexToShape.FindIndex(E)); + } + for (TopExp_Explorer exp(locShape,TopAbs_VERTEX); exp.More(); exp.Next()) + { + const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current()); + setId.insert(myIndexToShape.FindIndex(V)); + SCRUTE(myIndexToShape.FindIndex(V)); + } } - //********** - //} - //else if (strcmp(msgname,"Applied Hypothesis")==0) { - for (int ii = 0; ii < nb_meshsubgroup; ii++) + shapesId->length(setId.size()); + set::iterator iind; + int i=0; + for (iind = setId.begin(); iind != setId.end(); iind++) { - hdfGroupMeshId->InternalObjectIndentify(ii, msgname); - if (strcmp(msgname, "Mesh data") == 0) - { - //nothing - } - else if (strcmp(msgname, "Ref on shape") == 0) - { - //nothing - } - else if (strcmp(msgname, "Applied Hypothesis") == 0) - { - loadAppliedHypothesis(hdfGroupMeshId, _found, Study, myNewMesh, - aShape); - } - else if (strcmp(msgname, "Applied Algorithms") == 0) - { - loadAppliedAlgorithms(hdfGroupMeshId, _found, Study, myNewMesh, - aShape); - } - else if (string(msgname).substr(0, 9) == string("SubMeshes")) - { - loadSubMeshes(hdfGroupMeshId, msgname, Study, myNewMesh); - } + SCRUTE((*iind)); + shapesId[i] = (*iind); + SCRUTE(shapesId[i]); + i++; } - hdfGroupMeshId->CloseOnDisk(); + } + catch (SALOME_Exception& S_ex) + { + THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); + } + + return shapesId._retn(); } -/** - * Load the part of the study related to SMESH. +//============================================================================= +/*! + * SMESH_Gen_i::Compute + * + * Compute mesh on a shape */ -bool SMESH_Gen_i::Load(SALOMEDS::SComponent_ptr theComponent, - const SALOMEDS::TMPFile & theStream, const char *theURL, bool isMultiFile) -{ - MESSAGE("SMESH_Gen_i::Load"); - // Get temporary files location - TCollection_AsciiString tmpDir = - isMultiFile ? TCollection_AsciiString((char *)theURL) : SALOMEDS_Tool:: - GetTmpDir(); - - // Convert the stream into sequence of files to process - SALOMEDS::ListOfFileNames_var aFileSeq = - SALOMEDS_Tool::PutStreamToFiles(theStream, tmpDir.ToCString(), - isMultiFile); - - TCollection_AsciiString aStudyName(""); - if (isMultiFile) - aStudyName = - (SALOMEDS_Tool::GetNameFromPath(theComponent->GetStudy()->URL())); - - // Set names of temporary files - TCollection_AsciiString filename = - tmpDir + aStudyName + TCollection_AsciiString("_SMESH.hdf"); - TCollection_AsciiString hypofile = - tmpDir + aStudyName + TCollection_AsciiString("_SMESH_Hypo.txt"); - TCollection_AsciiString algofile = - tmpDir + aStudyName + TCollection_AsciiString("_SMESH_Algo.txt"); - TCollection_AsciiString meshfile = - tmpDir + aStudyName + TCollection_AsciiString("_SMESH_Mesh.med"); - - SALOMEDS::Study_var Study = theComponent->GetStudy(); - int studyId = Study->StudyId(); - SCRUTE(studyId); - - SALOMEDS::AttributeName_var aName; - - SALOMEDS::SComponent_var fathergeom = Study->FindComponent("GEOM"); - SALOMEDS::SComponent_var myGeomSComp = - SALOMEDS::SComponent::_narrow(fathergeom); - SCRUTE(fathergeom); - - char name[HDF_NAME_MAX_LEN + 1]; - map < int, HDFgroup * > hdf_subgroup; +//============================================================================= +CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, + GEOM::GEOM_Shape_ptr theShape ) + throw ( SALOME::SALOME_Exception ) +{ + Unexpect aCatch(SALOME_SalomeException); + MESSAGE( "SMESH_Gen_i::Compute" ); + + if ( CORBA::is_nil( theShape ) ) + THROW_SALOME_CORBA_EXCEPTION( "bad shape reference", + SALOME::BAD_PARAM ); + + if ( CORBA::is_nil( theMesh ) ) + THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference", + SALOME::BAD_PARAM ); + + try { + // get mesh servant + SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( theMesh ).in() ); + ASSERT( meshServant ); + if ( meshServant ) { + // get local TopoDS_Shape + TopoDS_Shape myLocShape = GetShapeReader()->GetShape( GetGeomEngine(), theShape ); + // call implementarion compute + ::SMESH_Mesh& myLocMesh = meshServant->GetImpl(); + return myGen.Compute( myLocMesh, myLocShape); + } + } + catch ( SALOME_Exception& S_ex ) { + MESSAGE( "Compute(): catch exception "<< S_ex.what() ); + } + catch ( ... ) { + MESSAGE( "Compute(): unknown exception " ); + } + return false; +} - //************* HDF file opening - HDFfile *hdf_file = new HDFfile(filename.ToCString()); - try - { - hdf_file->OpenOnDisk(HDF_RDONLY); +//============================================================================= +/*! + * SMESH_Gen_i::Save + * + * Save SMESH module's data + */ +//============================================================================= +SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, + const char* theURL, + bool isMultiFile ) +{ + INFOS( "SMESH_Gen_i::Save" ); + + ASSERT( theComponent->GetStudy()->StudyId() == myCurrentStudy->StudyId() ) + StudyContext* myStudyContext = GetCurrentStudyContext(); + + // Declare a byte stream + SALOMEDS::TMPFile_var aStreamFile; + + // Obtain a temporary dir + TCollection_AsciiString tmpDir = + ( isMultiFile ) ? TCollection_AsciiString( ( char* )theURL ) : SALOMEDS_Tool::GetTmpDir(); + + // Create a sequence of files processed + SALOMEDS::ListOfFileNames_var aFileSeq = new SALOMEDS::ListOfFileNames; + aFileSeq->length( NUM_TMP_FILES ); + + TCollection_AsciiString aStudyName( "" ); + if ( isMultiFile ) + aStudyName = ( SALOMEDS_Tool::GetNameFromPath( myCurrentStudy->URL() ) ); + + // Set names of temporary files + TCollection_AsciiString filename = + aStudyName + TCollection_AsciiString( "_SMESH.hdf" ); // for SMESH data itself + TCollection_AsciiString meshfile = + aStudyName + TCollection_AsciiString( "_SMESH_Mesh.med" ); // for mesh data to be stored in MED file + aFileSeq[ 0 ] = CORBA::string_dup( filename.ToCString() ); + aFileSeq[ 1 ] = CORBA::string_dup( meshfile.ToCString() ); + filename = tmpDir + filename; + meshfile = tmpDir + meshfile; + + HDFfile* aFile; + HDFdataset* aDataset; + HDFgroup* aTopGroup; + HDFgroup* aGroup; + HDFgroup* aSubGroup; + HDFgroup* aSubSubGroup; + hdf_size aSize[ 1 ]; + + // MED writer to be used by storage process + DriverMED_W_SMESHDS_Mesh myWriter; + myWriter.SetFile( meshfile.ToCString() ); + + // Write data + // ---> create HDF file + aFile = new HDFfile( filename.ToCString() ); + aFile->CreateOnDisk(); + + // --> iterator for top-level objects + SALOMEDS::ChildIterator_var itBig = myCurrentStudy->NewChildIterator( theComponent ); + for ( ; itBig->More(); itBig->Next() ) { + SALOMEDS::SObject_var gotBranch = itBig->Value(); + + // --> hypotheses root branch (only one for the study) + if ( gotBranch->Tag() == GetHypothesisRootTag() ) { + // create hypotheses root HDF group + aTopGroup = new HDFgroup( "Hypotheses", aFile ); + aTopGroup->CreateOnDisk(); + + // iterator for all hypotheses + SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( gotBranch ); + for ( ; it->More(); it->Next() ) { + SALOMEDS::SObject_var mySObject = it->Value(); + CORBA::Object_var anObject = SObjectToObject( mySObject ); + if ( !CORBA::is_nil( anObject ) ) { + SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow( anObject ); + if ( !myHyp->_is_nil() ) { + SMESH_Hypothesis_i* myImpl = dynamic_cast( GetServant( myHyp ).in() ); + if ( myImpl ) { + string hypname = string( myHyp->GetName() ); + string libname = string( myHyp->GetLibName() ); + int id = myStudyContext->findId( string( GetORB()->object_to_string( anObject ) ) ); + string hypdata = string( myImpl->SaveTo() ); + + // for each hypothesis create HDF group basing on its id + char hypGrpName[30]; + sprintf( hypGrpName, "Hypothesis %d", id ); + aGroup = new HDFgroup( hypGrpName, aTopGroup ); + aGroup->CreateOnDisk(); + // --> type name of hypothesis + aSize[ 0 ] = hypname.length() + 1; + aDataset = new HDFdataset( "Name", aGroup, HDF_STRING, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( ( char* )( hypname.c_str() ) ); + aDataset->CloseOnDisk(); + // --> server plugin library name of hypothesis + aSize[ 0 ] = libname.length() + 1; + aDataset = new HDFdataset( "LibName", aGroup, HDF_STRING, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( ( char* )( libname.c_str() ) ); + aDataset->CloseOnDisk(); + // --> persistent data of hypothesis + aSize[ 0 ] = hypdata.length() + 1; + aDataset = new HDFdataset( "Data", aGroup, HDF_STRING, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( ( char* )( hypdata.c_str() ) ); + aDataset->CloseOnDisk(); + // close hypothesis HDF group + aGroup->CloseOnDisk(); + } + } } - catch(HDFexception) - { - MESSAGE("Load(): " << filename << " not found!"); - return false; + } + // close hypotheses root HDF group + aTopGroup->CloseOnDisk(); + } + // --> algorithms root branch (only one for the study) + else if ( gotBranch->Tag() == GetAlgorithmsRootTag() ) { + // create algorithms root HDF group + aTopGroup = new HDFgroup( "Algorithms", aFile ); + aTopGroup->CreateOnDisk(); + + // iterator for all algorithms + SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( gotBranch ); + for ( ; it->More(); it->Next() ) { + SALOMEDS::SObject_var mySObject = it->Value(); + CORBA::Object_var anObject = SObjectToObject( mySObject ); + if ( !CORBA::is_nil( anObject ) ) { + SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow( anObject ); + if ( !myHyp->_is_nil() ) { + SMESH_Hypothesis_i* myImpl = dynamic_cast( GetServant( myHyp ).in() ); + if ( myImpl ) { + string hypname = string( myHyp->GetName() ); + string libname = string( myHyp->GetLibName() ); + int id = myStudyContext->findId( string( GetORB()->object_to_string( anObject ) ) ); + string hypdata = string( myImpl->SaveTo() ); + + // for each algorithm create HDF group basing on its id + char hypGrpName[30]; + sprintf( hypGrpName, "Algorithm %d", id ); + aGroup = new HDFgroup( hypGrpName, aTopGroup ); + aGroup->CreateOnDisk(); + // --> type name of algorithm + aSize[0] = hypname.length() + 1; + aDataset = new HDFdataset( "Name", aGroup, HDF_STRING, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( ( char* )( hypname.c_str() ) ); + aDataset->CloseOnDisk(); + // --> server plugin library name of hypothesis + aSize[0] = libname.length() + 1; + aDataset = new HDFdataset( "LibName", aGroup, HDF_STRING, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( ( char* )( libname.c_str() ) ); + aDataset->CloseOnDisk(); + // --> persistent data of algorithm + aSize[0] = hypdata.length() + 1; + aDataset = new HDFdataset( "Data", aGroup, HDF_STRING, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( ( char* )( hypdata.c_str() ) ); + aDataset->CloseOnDisk(); + // close algorithm HDF group + aGroup->CloseOnDisk(); + } + } } + } + // close algorithms root HDF group + aTopGroup->CloseOnDisk(); + } + // --> mesh objects roots branches + else if ( gotBranch->Tag() > GetAlgorithmsRootTag() ) { + CORBA::Object_var anObject = SObjectToObject( gotBranch ); + if ( !CORBA::is_nil( anObject ) ) { + SMESH::SMESH_Mesh_var myMesh = SMESH::SMESH_Mesh::_narrow( anObject ) ; + if ( !myMesh->_is_nil() ) { + SMESH_Mesh_i* myImpl = dynamic_cast( GetServant( myMesh ).in() ); + if ( myImpl ) { + int id = myStudyContext->findId( string( GetORB()->object_to_string( anObject ) ) ); + ::SMESH_Mesh& myLocMesh = myImpl->GetImpl(); + SMESHDS_Mesh* mySMESHDSMesh = myLocMesh.GetMeshDS(); + + // for each mesh open the HDF group basing on its id + char meshGrpName[ 30 ]; + sprintf( meshGrpName, "Mesh %d", id ); + aTopGroup = new HDFgroup( meshGrpName, aFile ); + aTopGroup->CreateOnDisk(); + + // --> put dataset to hdf file which is a flag that mesh has data + string strHasData = "0"; + // check if the mesh is not empty + if ( mySMESHDSMesh->NbNodes() > 0 ) { + // write mesh data to med file + myWriter.SetMesh( mySMESHDSMesh ); + myWriter.SetMeshId( id ); + strHasData = "1"; + } + aSize[ 0 ] = strHasData.length() + 1; + aDataset = new HDFdataset( "Has data", aTopGroup, HDF_STRING, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( ( char* )( strHasData.c_str() ) ); + aDataset->CloseOnDisk(); + + // write reference on a shape if exists + SALOMEDS::SObject_var myRef; + bool found = gotBranch->FindSubObject( GetRefOnShapeTag(), myRef ); + if ( found ) { + SALOMEDS::SObject_var myShape; + bool ok = myRef->ReferencedObject( myShape ); + if ( ok ) { + string myRefOnObject = myShape->GetID(); + if ( myRefOnObject.length() > 0 ) { + aSize[ 0 ] = myRefOnObject.length() + 1; + aDataset = new HDFdataset( "Ref on shape", aTopGroup, HDF_STRING, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) ); + aDataset->CloseOnDisk(); + } + } + } + + // write applied hypotheses if exist + SALOMEDS::SObject_var myHypBranch; + found = gotBranch->FindSubObject( GetRefOnAppliedHypothesisTag(), myHypBranch ); + if ( found ) { + aGroup = new HDFgroup( "Applied Hypotheses", aTopGroup ); + aGroup->CreateOnDisk(); + + SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( myHypBranch ); + int hypNb = 0; + for ( ; it->More(); it->Next() ) { + SALOMEDS::SObject_var mySObject = it->Value(); + SALOMEDS::SObject_var myRefOnHyp; + bool ok = mySObject->ReferencedObject( myRefOnHyp ); + if ( ok ) { + // san - it is impossible to recover applied hypotheses + // using their entries within Load() method, + // for there are no AttributeIORs in the study when Load() is working. + // Hence, it is better to store persistent IDs of hypotheses as references to them + + //string myRefOnObject = myRefOnHyp->GetID(); + CORBA::Object_var anObject = SObjectToObject( myRefOnHyp ); + int id = myStudyContext->findId( string( GetORB()->object_to_string( anObject ) ) ); + //if ( myRefOnObject.length() > 0 ) { + //aSize[ 0 ] = myRefOnObject.length() + 1; + char hypName[ 30 ], hypId[ 30 ]; + sprintf( hypName, "Hyp %d", ++hypNb ); + sprintf( hypId, "%d", id ); + aSize[ 0 ] = strlen( hypId ) + 1; + aDataset = new HDFdataset( hypName, aGroup, HDF_STRING, aSize, 1 ); + aDataset->CreateOnDisk(); + //aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) ); + aDataset->WriteOnDisk( hypId ); + aDataset->CloseOnDisk(); + //} + } + } + aGroup->CloseOnDisk(); + } + + // write applied algorithms if exist + SALOMEDS::SObject_var myAlgoBranch; + found = gotBranch->FindSubObject( GetRefOnAppliedAlgorithmsTag(), myAlgoBranch ); + if ( found ) { + aGroup = new HDFgroup( "Applied Algorithms", aTopGroup ); + aGroup->CreateOnDisk(); + + SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( myAlgoBranch ); + int algoNb = 0; + for ( ; it->More(); it->Next() ) { + SALOMEDS::SObject_var mySObject = it->Value(); + SALOMEDS::SObject_var myRefOnAlgo; + bool ok = mySObject->ReferencedObject( myRefOnAlgo ); + if ( ok ) { + // san - it is impossible to recover applied algorithms + // using their entries within Load() method, + // for there are no AttributeIORs in the study when Load() is working. + // Hence, it is better to store persistent IDs of algorithms as references to them + + //string myRefOnObject = myRefOnAlgo->GetID(); + CORBA::Object_var anObject = SObjectToObject( myRefOnAlgo ); + int id = myStudyContext->findId( string( GetORB()->object_to_string( anObject ) ) ); + //if ( myRefOnObject.length() > 0 ) { + //aSize[ 0 ] = myRefOnObject.length() + 1; + char algoName[ 30 ], algoId[ 30 ]; + sprintf( algoName, "Algo %d", ++algoNb ); + sprintf( algoId, "%d", id ); + aSize[ 0 ] = strlen( algoId ) + 1; + aDataset = new HDFdataset( algoName, aGroup, HDF_STRING, aSize, 1 ); + aDataset->CreateOnDisk(); + //aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) ); + aDataset->WriteOnDisk( algoId ); + aDataset->CloseOnDisk(); + //} + } + } + aGroup->CloseOnDisk(); + } + + // --> submesh objects sub-branches + for ( int i = GetSubMeshOnVertexTag(); i <= GetSubMeshOnCompoundTag(); i++ ) { + SALOMEDS::SObject_var mySubmeshBranch; + found = gotBranch->FindSubObject( i, mySubmeshBranch ); + if ( found ) { + char name_meshgroup[ 30 ]; + if ( i == GetSubMeshOnVertexTag() ) + strcpy( name_meshgroup, "SubMeshes On Vertex" ); + else if ( i == GetSubMeshOnEdgeTag() ) + strcpy( name_meshgroup, "SubMeshes On Edge" ); + else if ( i == GetSubMeshOnFaceTag() ) + strcpy( name_meshgroup, "SubMeshes On Face" ); + else if ( i == GetSubMeshOnSolidTag() ) + strcpy( name_meshgroup, "SubMeshes On Solid" ); + else if ( i == GetSubMeshOnCompoundTag() ) + strcpy( name_meshgroup, "SubMeshes On Compound" ); + + // for each type of submeshes create container HDF group + aGroup = new HDFgroup( name_meshgroup, aTopGroup ); + aGroup->CreateOnDisk(); + + // iterator for all submeshes of given type + SALOMEDS::ChildIterator_var itSM = myCurrentStudy->NewChildIterator( mySubmeshBranch ); + for ( ; itSM->More(); itSM->Next() ) { + SALOMEDS::SObject_var mySObject = itSM->Value(); + CORBA::Object_var anSubObject = SObjectToObject( mySObject ); + if ( !CORBA::is_nil( anSubObject ) ) { + SMESH::SMESH_subMesh_var mySubMesh = SMESH::SMESH_subMesh::_narrow( anSubObject ) ; + int subid = myStudyContext->findId( string( GetORB()->object_to_string( anSubObject ) ) ); + + // for each mesh open the HDF group basing on its id + char submeshGrpName[ 30 ]; + sprintf( submeshGrpName, "SubMesh %d", subid ); + aSubGroup = new HDFgroup( submeshGrpName, aGroup ); + aSubGroup->CreateOnDisk(); + +// // Put submesh data to MED convertor +// if ( myImpl->_mapSubMesh.find( mySubMesh->GetId() ) != myImpl->_mapSubMesh.end() ) { +// MESSAGE( "VSR - SMESH_Gen_i::Save(): saving submesh with ID = " +// << mySubMesh->GetId() << " to MED file" ); +// ::SMESH_subMesh* aLocalSubmesh = myImpl->_mapSubMesh[mySubMesh->GetId()]; +// myWriter.AddSubMesh( aLocalSubmesh->GetSubMeshDS(), subid ); +// } + + // write reference on a shape if exists + SALOMEDS::SObject_var mySubRef; + found = mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef ); + if ( found ) { + SALOMEDS::SObject_var myShape; + bool ok = mySubRef->ReferencedObject( myShape ); + if ( ok ) { + string myRefOnObject = myShape->GetID(); + if ( myRefOnObject.length() > 0 ) { + aSize[ 0 ] = myRefOnObject.length() + 1; + aDataset = new HDFdataset( "Ref on shape", aSubGroup, HDF_STRING, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) ); + aDataset->CloseOnDisk(); + } + } + } + + // write applied hypotheses if exist + SALOMEDS::SObject_var mySubHypBranch; + found = mySObject->FindSubObject( GetRefOnAppliedHypothesisTag(), mySubHypBranch ); + if ( found ) { + aSubSubGroup = new HDFgroup( "Applied Hypotheses", aSubGroup ); + aSubSubGroup->CreateOnDisk(); + + SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( mySubHypBranch ); + int hypNb = 0; + for ( ; it->More(); it->Next() ) { + SALOMEDS::SObject_var mySubSObject = it->Value(); + SALOMEDS::SObject_var myRefOnHyp; + bool ok = mySubSObject->ReferencedObject( myRefOnHyp ); + if ( ok ) { + //string myRefOnObject = myRefOnHyp->GetID(); + CORBA::Object_var anObject = SObjectToObject( myRefOnHyp ); + int id = myStudyContext->findId( string( GetORB()->object_to_string( anObject ) ) ); + //if ( myRefOnObject.length() > 0 ) { + //aSize[ 0 ] = myRefOnObject.length() + 1; + char hypName[ 30 ], hypId[ 30 ]; + sprintf( hypName, "Hyp %d", ++hypNb ); + sprintf( hypId, "%d", id ); + aSize[ 0 ] = strlen( hypId ) + 1; + aDataset = new HDFdataset( hypName, aSubSubGroup, HDF_STRING, aSize, 1 ); + aDataset->CreateOnDisk(); + //aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) ); + aDataset->WriteOnDisk( hypId ); + aDataset->CloseOnDisk(); + //} + } + } + aSubSubGroup->CloseOnDisk(); + } + + // write applied algorithms if exist + SALOMEDS::SObject_var mySubAlgoBranch; + found = mySObject->FindSubObject( GetRefOnAppliedAlgorithmsTag(), mySubAlgoBranch ); + if ( found ) { + aSubSubGroup = new HDFgroup( "Applied Algorithms", aSubGroup ); + aSubSubGroup->CreateOnDisk(); + + SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( mySubAlgoBranch ); + int algoNb = 0; + for ( ; it->More(); it->Next() ) { + SALOMEDS::SObject_var mySubSObject = it->Value(); + SALOMEDS::SObject_var myRefOnAlgo; + bool ok = mySubSObject->ReferencedObject( myRefOnAlgo ); + if ( ok ) { + //string myRefOnObject = myRefOnAlgo->GetID(); + CORBA::Object_var anObject = SObjectToObject( myRefOnAlgo ); + int id = myStudyContext->findId( string( GetORB()->object_to_string( anObject ) ) ); + //if ( myRefOnObject.length() > 0 ) { + //aSize[ 0 ] = myRefOnObject.length() + 1; + char algoName[ 30 ], algoId[ 30 ]; + sprintf( algoName, "Algo %d", ++algoNb ); + sprintf( algoId, "%d", id ); + aSize[ 0 ] = strlen( algoId ) + 1; + aDataset = new HDFdataset( algoName, aSubSubGroup, HDF_STRING, aSize, 1 ); + aDataset->CreateOnDisk(); + //aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) ); + aDataset->WriteOnDisk( algoId ); + aDataset->CloseOnDisk(); + //} + } + } + aSubSubGroup->CloseOnDisk(); + } + // close submesh HDF group + aSubGroup->CloseOnDisk(); + } + } + // close container of submeshes by type HDF group + aGroup->CloseOnDisk(); + } + } + // All sub-meshes will be stored in MED file + myWriter.AddAllSubMeshes(); + + // groups root sub-branch + SALOMEDS::SObject_var myGroupsBranch; + for ( int i = GetNodeGroupsTag(); i <= GetVolumeGroupsTag(); i++ ) { + found = gotBranch->FindSubObject( i, myGroupsBranch ); + if ( found ) { + char name_group[ 30 ]; + if ( i == GetNodeGroupsTag() ) + strcpy( name_group, "Groups of Nodes" ); + else if ( i == GetEdgeGroupsTag() ) + strcpy( name_group, "Groups of Edges" ); + else if ( i == GetFaceGroupsTag() ) + strcpy( name_group, "Groups of Faces" ); + else if ( i == GetVolumeGroupsTag() ) + strcpy( name_group, "Groups of Volumes" ); + + aGroup = new HDFgroup( name_group, aTopGroup ); + aGroup->CreateOnDisk(); + + SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( myGroupsBranch ); + int grpNb = 0; + for ( ; it->More(); it->Next() ) { + SALOMEDS::SObject_var mySObject = it->Value(); + CORBA::Object_var aSubObject = SObjectToObject( mySObject ); + if ( !CORBA::is_nil( aSubObject ) ) { + SMESH_Group_i* myGroupImpl = dynamic_cast( GetServant( aSubObject ).in() ); + if ( !myGroupImpl ) + continue; + + int anId = myStudyContext->findId( string( GetORB()->object_to_string( aSubObject ) ) ); + + // For each group, create a dataset named "Group " + // and store the group's user name into it + char grpName[ 30 ]; + sprintf( grpName, "Group %d", anId ); + char* aUserName = myGroupImpl->GetName(); + aSize[ 0 ] = strlen( aUserName ) + 1; + + aDataset = new HDFdataset( grpName, aGroup, HDF_STRING, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( aUserName ); + aDataset->CloseOnDisk(); + + // Store the group contents into MED file + if ( myLocMesh.GetGroup( myGroupImpl->GetLocalID() ) ) { + MESSAGE( "VSR - SMESH_Gen_i::Save(): saving group with StoreName = " + << grpName << " to MED file" ); + SMESHDS_Group* aGrpDS = myLocMesh.GetGroup( myGroupImpl->GetLocalID() )->GetGroupDS(); + aGrpDS->SetStoreName( grpName ); + + // Pass SMESHDS_Group to MED writer + myWriter.AddGroup( aGrpDS ); + } + } + } + aGroup->CloseOnDisk(); + } + } - //**************************** + // Flush current mesh information into MED file + if ( strcmp( strHasData.c_str(), "1" ) == 0 ) + myWriter.Add(); - int nb_group = hdf_file->nInternalObjects(); - SCRUTE(nb_group); - for (int i = 0; i < nb_group; i++) - { - hdf_file->InternalObjectIndentify(i, name); - if (strcmp(name, "Hypothesis") == 0) - loadHypothesis(name, hdf_file, hypofile.ToCString(), studyId); - else if (strcmp(name, "Algorithms") == 0) - loadAlgorithms(name, hdf_file, algofile.ToCString(), studyId); - else if (string(name).substr(0, 4) == string("Mesh")) - loadMesh(name, hdf_file, meshfile.ToCString(), Study); + // close mesh HDF group + aTopGroup->CloseOnDisk(); + } } + } + } + } - MESSAGE("End of SMESH_Gen::Load"); + // close HDF file + aFile->CloseOnDisk(); + delete aFile; - hdf_file->CloseOnDisk(); + // Convert temporary files to stream + aStreamFile = SALOMEDS_Tool::PutFilesToStream( tmpDir.ToCString(), aFileSeq.in(), isMultiFile ); - // Remove temporary files created from the stream - if (isMultiFile) - SALOMEDS_Tool::RemoveTemporaryFiles(tmpDir.ToCString(), aFileSeq.in(), - true); + // Remove temporary files and directory + if ( !isMultiFile ) + SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true ); - return true; + INFOS( "SMESH_Gen_i::Save() completed" ); + return aStreamFile._retn(); } -bool SMESH_Gen_i::LoadASCII(SALOMEDS::SComponent_ptr theComponent, - const SALOMEDS::TMPFile & theStream, const char *theURL, bool isMultiFile) +//============================================================================= +/*! + * SMESH_Gen_i::SaveASCII + * + * Save SMESH module's data in ASCII format (not implemented yet) + */ +//============================================================================= + +SALOMEDS::TMPFile* SMESH_Gen_i::SaveASCII( SALOMEDS::SComponent_ptr theComponent, + const char* theURL, + bool isMultiFile ) { + MESSAGE( "SMESH_Gen_i::SaveASCII" ); + SALOMEDS::TMPFile_var aStreamFile = Save( theComponent, theURL, isMultiFile ); + return aStreamFile._retn(); +} + +//============================================================================= +/*! + * SMESH_Gen_i::loadGeomData + * + * Load GEOM module data + */ +//============================================================================= + +void SMESH_Gen_i::loadGeomData( SALOMEDS::SComponent_ptr theCompRoot ) { - return Load(theComponent, theStream, theURL, isMultiFile); + if ( theCompRoot->_is_nil() ) + return; + + SALOMEDS::Study_var aStudy = SALOMEDS::Study::_narrow( theCompRoot->GetStudy() ); + if ( aStudy->_is_nil() ) + return; + + SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder(); + aStudyBuilder->LoadWith( theCompRoot, GetGeomEngine() ); } //============================================================================= /*! - * + * SMESH_Gen_i::Load + * + * Load SMESH module's data */ //============================================================================= -void SMESH_Gen_i::Close(SALOMEDS::SComponent_ptr theComponent) +bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, + const SALOMEDS::TMPFile& theStream, + const char* theURL, + bool isMultiFile ) { - MESSAGE("Close"); - SALOMEDS::Study_var aStudy = theComponent->GetStudy(); - SALOMEDS::ChildIterator_var itBig = aStudy->NewChildIterator(theComponent); - for (; itBig->More(); itBig->Next()) - { - SALOMEDS::SObject_var gotBranch = itBig->Value(); - - // branch 1 : hypothesis - if (gotBranch->Tag() == Tag_HypothesisRoot || - gotBranch->Tag() == Tag_AlgorithmsRoot) - { - SALOMEDS::ChildIterator_var it = - aStudy->NewChildIterator(gotBranch); - for (; it->More(); it->Next()) - { - SALOMEDS::SObject_var mySObject = it->Value(); - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::AttributeIOR_var anIOR; - if (mySObject->FindAttribute(anAttr, "AttributeIOR")) - { - anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - SMESH::SMESH_Hypothesis_var myHyp = - SMESH::SMESH_Hypothesis::_narrow(_orb-> - string_to_object(anIOR->Value())); - char objectId[10]; - sprintf(objectId, "%ld", myHyp->GetId()); -// cout<<"********** delete Hyp "< - string_to_object(anIOR->Value())); - } - } + INFOS( "SMESH_Gen_i::Load" ); + + ASSERT( theComponent->GetStudy()->StudyId() == myCurrentStudy->StudyId() ) + StudyContext* myStudyContext = GetCurrentStudyContext(); + + // Get temporary files location + TCollection_AsciiString tmpDir = + isMultiFile ? TCollection_AsciiString( ( char* )theURL ) : SALOMEDS_Tool::GetTmpDir(); + + // Convert the stream into sequence of files to process + SALOMEDS::ListOfFileNames_var aFileSeq = SALOMEDS_Tool::PutStreamToFiles( theStream, + tmpDir.ToCString(), + isMultiFile ); + TCollection_AsciiString aStudyName( "" ); + if ( isMultiFile ) + aStudyName = ( SALOMEDS_Tool::GetNameFromPath( myCurrentStudy->URL() ) ); + + // Set names of temporary files + TCollection_AsciiString filename = tmpDir + aStudyName + TCollection_AsciiString( "_SMESH.hdf" ); + TCollection_AsciiString meshfile = tmpDir + aStudyName + TCollection_AsciiString( "_SMESH_Mesh.med" ); + + int size; + HDFfile* aFile; + HDFdataset* aDataset; + HDFgroup* aTopGroup; + HDFgroup* aGroup; + HDFgroup* aSubGroup; + HDFgroup* aSubSubGroup; + + // Read data + // ---> open HDF file + aFile = new HDFfile( filename.ToCString() ); + try { + aFile->OpenOnDisk( HDF_RDONLY ); + } + catch ( HDFexception ) { + MESSAGE( "Load(): " << filename << " not found!" ); + return false; + } + + DriverMED_R_SMESHDS_Mesh myReader; + myReader.SetFile( meshfile.ToCString() ); + + // get total number of top-level groups + int aNbGroups = aFile->nInternalObjects(); + if ( aNbGroups > 0 ) { + // --> in first turn we should read&create hypotheses + if ( aFile->ExistInternalObject( "Hypotheses" ) ) { + // open hypotheses root HDF group + aTopGroup = new HDFgroup( "Hypotheses", aFile ); + aTopGroup->OpenOnDisk(); + + // get number of hypotheses + int aNbObjects = aTopGroup->nInternalObjects(); + for ( int j = 0; j < aNbObjects; j++ ) { + // try to identify hypothesis + char hypGrpName[ HDF_NAME_MAX_LEN+1 ]; + aTopGroup->InternalObjectIndentify( j, hypGrpName ); + + if ( string( hypGrpName ).substr( 0, 10 ) == string( "Hypothesis" ) ) { + // open hypothesis group + aGroup = new HDFgroup( hypGrpName, aTopGroup ); + aGroup->OpenOnDisk(); + + // --> get hypothesis id + int id = atoi( string( hypGrpName ).substr( 10 ).c_str() ); + string hypname; + string libname; + string hypdata; + + // get number of datasets + int aNbSubObjects = aGroup->nInternalObjects(); + for ( int k = 0; k < aNbSubObjects; k++ ) { + // identify dataset + char name_of_subgroup[ HDF_NAME_MAX_LEN+1 ]; + aGroup->InternalObjectIndentify( k, name_of_subgroup ); + // --> get hypothesis name + if ( strcmp( name_of_subgroup, "Name" ) == 0 ) { + aDataset = new HDFdataset( name_of_subgroup, aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* hypname_str = new char[ size ]; + aDataset->ReadFromDisk( hypname_str ); + hypname = string( hypname_str ); + delete hypname_str; + aDataset->CloseOnDisk(); + } + // --> get hypothesis plugin library name + if ( strcmp( name_of_subgroup, "LibName" ) == 0 ) { + aDataset = new HDFdataset( name_of_subgroup, aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* libname_str = new char[ size ]; + aDataset->ReadFromDisk( libname_str ); + SCRUTE( libname_str ); + libname = string( libname_str ); + delete libname_str; + aDataset->CloseOnDisk(); + } + // --> get hypothesis data + if ( strcmp( name_of_subgroup, "Data" ) == 0 ) { + aDataset = new HDFdataset( name_of_subgroup, aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* hypdata_str = new char[ size ]; + aDataset->ReadFromDisk( hypdata_str ); + hypdata = string( hypdata_str ); + delete hypdata_str; + aDataset->CloseOnDisk(); + } + } + // close hypothesis HDF group + aGroup->CloseOnDisk(); + + // --> restore hypothesis from data + if ( id > 0 && !hypname.empty()/* && !hypdata.empty()*/ ) { // VSR : persistent data can be empty + MESSAGE("VSR - load hypothesis : id = " << id << + ", name = " << hypname.c_str() << ", persistent string = " << hypdata.c_str()); + SMESH::SMESH_Hypothesis_var myHyp; + + try { // protect persistence mechanism against exceptions + myHyp = this->createHypothesis( hypname.c_str(), libname.c_str() ); + } + catch (...) { + MESSAGE( "Exception during hypothesis creation" ); + } + + SMESH_Hypothesis_i* myImpl = dynamic_cast( GetServant( myHyp ).in() ); + if ( myImpl ) { + myImpl->LoadFrom( hypdata.c_str() ); + string iorString = GetORB()->object_to_string( myHyp ); + int newId = myStudyContext->findId( iorString ); + myStudyContext->mapOldToNew( id, newId ); + } + else + MESSAGE( "VSR - SMESH_Gen::Load - can't get servant" ); + } + } + } + // close hypotheses root HDF group + aTopGroup->CloseOnDisk(); + } + + // --> then we should read&create algorithms + if ( aFile->ExistInternalObject( "Algorithms" ) ) { + // open algorithms root HDF group + aTopGroup = new HDFgroup( "Algorithms", aFile ); + aTopGroup->OpenOnDisk(); + + // get number of algorithms + int aNbObjects = aTopGroup->nInternalObjects(); + for ( int j = 0; j < aNbObjects; j++ ) { + // try to identify algorithm + char hypGrpName[ HDF_NAME_MAX_LEN+1 ]; + aTopGroup->InternalObjectIndentify( j, hypGrpName ); + + if ( string( hypGrpName ).substr( 0, 9 ) == string( "Algorithm" ) ) { + // open algorithm group + aGroup = new HDFgroup( hypGrpName, aTopGroup ); + aGroup->OpenOnDisk(); + + // --> get algorithm id + int id = atoi( string( hypGrpName ).substr( 9 ).c_str() ); + string hypname; + string libname; + string hypdata; + + // get number of datasets + int aNbSubObjects = aGroup->nInternalObjects(); + for ( int k = 0; k < aNbSubObjects; k++ ) { + // identify dataset + char name_of_subgroup[ HDF_NAME_MAX_LEN+1 ]; + aGroup->InternalObjectIndentify( k, name_of_subgroup ); + // --> get algorithm name + if ( strcmp( name_of_subgroup, "Name" ) == 0 ) { + aDataset = new HDFdataset( name_of_subgroup, aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* hypname_str = new char[ size ]; + aDataset->ReadFromDisk( hypname_str ); + hypname = string( hypname_str ); + delete hypname_str; + aDataset->CloseOnDisk(); + } + // --> get algorithm plugin library name + if ( strcmp( name_of_subgroup, "LibName" ) == 0 ) { + aDataset = new HDFdataset( name_of_subgroup, aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* libname_str = new char[ size ]; + aDataset->ReadFromDisk( libname_str ); + SCRUTE( libname_str ); + libname = string( libname_str ); + delete libname_str; + aDataset->CloseOnDisk(); + } + // --> get algorithm data + if ( strcmp( name_of_subgroup, "Data" ) == 0 ) { + aDataset = new HDFdataset( name_of_subgroup, aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* hypdata_str = new char[ size ]; + aDataset->ReadFromDisk( hypdata_str ); + SCRUTE( hypdata_str ); + hypdata = string( hypdata_str ); + delete hypdata_str; + aDataset->CloseOnDisk(); + } + } + // close algorithm HDF group + aGroup->CloseOnDisk(); + + // --> restore algorithm from data + if ( id > 0 && !hypname.empty()/* && !hypdata.empty()*/ ) { // VSR : persistent data can be empty + MESSAGE("VSR - load algo : id = " << id << + ", name = " << hypname.c_str() << ", persistent string = " << hypdata.c_str()); + SMESH::SMESH_Hypothesis_var myHyp; + + try { // protect persistence mechanism against exceptions + myHyp = this->createHypothesis( hypname.c_str(), libname.c_str() ); + } + catch (...) { + MESSAGE( "Exception during hypothesis creation" ); + } + + SMESH_Hypothesis_i* myImpl = dynamic_cast( GetServant( myHyp ).in() ); + if ( myImpl ) { + myImpl->LoadFrom( hypdata.c_str() ); + string iorString = GetORB()->object_to_string( myHyp ); + int newId = myStudyContext->findId( iorString ); + myStudyContext->mapOldToNew( id, newId ); + } + else + MESSAGE( "VSR - SMESH_Gen::Load - can't get servant" ); + } + } + } + // close algorithms root HDF group + aTopGroup->CloseOnDisk(); + } + + // --> the rest groups should be meshes + for ( int i = 0; i < aNbGroups; i++ ) { + // identify next group + char meshName[ HDF_NAME_MAX_LEN+1 ]; + aFile->InternalObjectIndentify( i, meshName ); + + if ( string( meshName ).substr( 0, 4 ) == string( "Mesh" ) ) { + // --> get mesh id + int id = atoi( string( meshName ).substr( 4 ).c_str() ); + if ( id <= 0 ) + continue; + + bool hasData = false; + + // open mesh HDF group + aTopGroup = new HDFgroup( meshName, aFile ); + aTopGroup->OpenOnDisk(); + + // get number of child HDF objects + int aNbObjects = aTopGroup->nInternalObjects(); + if ( aNbObjects > 0 ) { + // create mesh + MESSAGE( "VSR - load mesh : id = " << id ); + SMESH::SMESH_Mesh_var myNewMesh = this->createMesh(); + SMESH_Mesh_i* myNewMeshImpl = dynamic_cast( GetServant( myNewMesh ).in() ); + if ( !myNewMeshImpl ) + continue; + string iorString = GetORB()->object_to_string( myNewMesh ); + int newId = myStudyContext->findId( iorString ); + myStudyContext->mapOldToNew( id, newId ); + + ::SMESH_Mesh& myLocMesh = myNewMeshImpl->GetImpl(); + SMESHDS_Mesh* mySMESHDSMesh = myLocMesh.GetMeshDS(); + + // try to find mesh data dataset + if ( aTopGroup->ExistInternalObject( "Has data" ) ) { + // load mesh "has data" flag + aDataset = new HDFdataset( "Has data", aTopGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* strHasData = new char[ size ]; + aDataset->ReadFromDisk( strHasData ); + aDataset->CloseOnDisk(); + if ( strcmp( strHasData, "1") == 0 ) { + // read mesh data from MED file + myReader.SetMesh( mySMESHDSMesh ); + myReader.SetMeshId( id ); + myReader.ReadMySelf(); + hasData = true; + } + } + + // try to read and set reference to shape + GEOM::GEOM_Shape_var aShape; + if ( aTopGroup->ExistInternalObject( "Ref on shape" ) ) { + // load mesh "Ref on shape" - it's an entry to SObject + aDataset = new HDFdataset( "Ref on shape", aTopGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* refFromFile = new char[ size ]; + aDataset->ReadFromDisk( refFromFile ); + aDataset->CloseOnDisk(); + if ( strlen( refFromFile ) > 0 ) { + SALOMEDS::SObject_var shapeSO = myCurrentStudy->FindObjectID( refFromFile ); + + // Make sure GEOM data are loaded first + loadGeomData( shapeSO->GetFatherComponent() ); + + CORBA::Object_var shapeObject = SObjectToObject( shapeSO ); + if ( !CORBA::is_nil( shapeObject ) ) { + aShape = GEOM::GEOM_Shape::_narrow( shapeObject ); + if ( !aShape->_is_nil() ) + myNewMeshImpl->setShape( aShape ); + } + } + } + + // try to get applied hypotheses + if ( aTopGroup->ExistInternalObject( "Applied Hypotheses" ) ) { + aGroup = new HDFgroup( "Applied Hypotheses", aTopGroup ); + aGroup->OpenOnDisk(); + // get number of applied hypotheses + int aNbSubObjects = aGroup->nInternalObjects(); + MESSAGE( "VSR - number of applied hypotheses = " << aNbSubObjects ); + for ( int j = 0; j < aNbSubObjects; j++ ) { + char name_dataset[ HDF_NAME_MAX_LEN+1 ]; + aGroup->InternalObjectIndentify( j, name_dataset ); + // check if it is a hypothesis + if ( string( name_dataset ).substr( 0, 3 ) == string( "Hyp" ) ) { + aDataset = new HDFdataset( name_dataset, aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* refFromFile = new char[ size ]; + aDataset->ReadFromDisk( refFromFile ); + aDataset->CloseOnDisk(); + + // san - it is impossible to recover applied hypotheses using their entries within Load() method + + //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile ); + //CORBA::Object_var hypObject = SObjectToObject( hypSO ); + int id = atoi( refFromFile ); + string anIOR = myStudyContext->getIORbyOldId( id ); + if ( !anIOR.empty() ) { + CORBA::Object_var hypObject = GetORB()->string_to_object( anIOR.c_str() ); + if ( !CORBA::is_nil( hypObject ) ) { + SMESH::SMESH_Hypothesis_var anHyp = SMESH::SMESH_Hypothesis::_narrow( hypObject ); + if ( !anHyp->_is_nil() && !aShape->_is_nil() ) + myNewMeshImpl->addHypothesis( aShape, anHyp ); + } + } + } + } + aGroup->CloseOnDisk(); + } + + // try to get applied algorithms + if ( aTopGroup->ExistInternalObject( "Applied Algorithms" ) ) { + aGroup = new HDFgroup( "Applied Algorithms", aTopGroup ); + aGroup->OpenOnDisk(); + // get number of applied algorithms + int aNbSubObjects = aGroup->nInternalObjects(); + MESSAGE( "VSR - number of applied algos " << aNbSubObjects ); + for ( int j = 0; j < aNbSubObjects; j++ ) { + char name_dataset[ HDF_NAME_MAX_LEN+1 ]; + aGroup->InternalObjectIndentify( j, name_dataset ); + // check if it is an algorithm + if ( string( name_dataset ).substr( 0, 4 ) == string( "Algo" ) ) { + aDataset = new HDFdataset( name_dataset, aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* refFromFile = new char[ size ]; + aDataset->ReadFromDisk( refFromFile ); + aDataset->CloseOnDisk(); + + // san - it is impossible to recover applied algorithms using their entries within Load() method + + //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile ); + //CORBA::Object_var hypObject = SObjectToObject( hypSO ); + int id = atoi( refFromFile ); + string anIOR = myStudyContext->getIORbyOldId( id ); + if ( !anIOR.empty() ) { + CORBA::Object_var hypObject = GetORB()->string_to_object( anIOR.c_str() ); + if ( !CORBA::is_nil( hypObject ) ) { + SMESH::SMESH_Hypothesis_var anHyp = SMESH::SMESH_Hypothesis::_narrow( hypObject ); + if ( !anHyp->_is_nil() && !aShape->_is_nil() ) + myNewMeshImpl->addHypothesis( aShape, anHyp ); + } } - // branch 2 : algorithms - else if (gotBranch->Tag() >= 3) - { - SALOMEDS::ChildIterator_var it = - aStudy->NewChildIterator(gotBranch); - for (; it->More(); it->Next()) - { - SALOMEDS::SObject_var mySObject = it->Value(); - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::AttributeIOR_var anIOR; - if (mySObject->FindAttribute(anAttr, "AttributeIOR")) - { - anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - SMESH::SMESH_Mesh_var myMesh = - SMESH::SMESH_Mesh::_narrow(_orb-> - string_to_object(anIOR->Value())); - if (!myMesh->_is_nil()) - { - char objectId[10]; - sprintf(objectId, "%ld", myMesh->GetId()); -// cout<<"********** delete Mesh "< - string_to_object(anIOR->Value())); - if (!mySubMesh->_is_nil()) - { - char objectId[10]; - sprintf(objectId, "%ld", mySubMesh->GetId()); -// cout<<"********** delete SubMesh "<CloseOnDisk(); + } + + // --> try to find submeshes containers for each type of submesh + for ( int j = GetSubMeshOnVertexTag(); j <= GetSubMeshOnCompoundTag(); j++ ) { + char name_meshgroup[ 30 ]; + if ( j == GetSubMeshOnVertexTag() ) + strcpy( name_meshgroup, "SubMeshes On Vertex" ); + else if ( j == GetSubMeshOnEdgeTag() ) + strcpy( name_meshgroup, "SubMeshes On Edge" ); + else if ( j == GetSubMeshOnFaceTag() ) + strcpy( name_meshgroup, "SubMeshes On Face" ); + else if ( j == GetSubMeshOnSolidTag() ) + strcpy( name_meshgroup, "SubMeshes On Solid" ); + else if ( j == GetSubMeshOnCompoundTag() ) + strcpy( name_meshgroup, "SubMeshes On Compound" ); + + // try to get submeshes container HDF group + if ( aTopGroup->ExistInternalObject( name_meshgroup ) ) { + // open submeshes containers HDF group + aGroup = new HDFgroup( name_meshgroup, aTopGroup ); + aGroup->OpenOnDisk(); + + // get number of submeshes + int aNbSubMeshes = aGroup->nInternalObjects(); + for ( int k = 0; k < aNbSubMeshes; k++ ) { + // identify submesh + char name_submeshgroup[ HDF_NAME_MAX_LEN+1 ]; + aGroup->InternalObjectIndentify( k, name_submeshgroup ); + if ( string( name_submeshgroup ).substr( 0, 7 ) == string( "SubMesh" ) ) { + // --> get submesh id + int subid = atoi( string( name_submeshgroup ).substr( 7 ).c_str() ); + if ( subid <= 0 ) + continue; + // open submesh HDF group + aSubGroup = new HDFgroup( name_submeshgroup, aGroup ); + aSubGroup->OpenOnDisk(); + + // try to read and set reference to subshape + GEOM::GEOM_Shape_var aSubShape; + SMESH::SMESH_subMesh_var aSubMesh; + + if ( aSubGroup->ExistInternalObject( "Ref on shape" ) ) { + // load submesh "Ref on shape" - it's an entry to SObject + aDataset = new HDFdataset( "Ref on shape", aSubGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* refFromFile = new char[ size ]; + aDataset->ReadFromDisk( refFromFile ); + aDataset->CloseOnDisk(); + if ( strlen( refFromFile ) > 0 ) { + SALOMEDS::SObject_var subShapeSO = myCurrentStudy->FindObjectID( refFromFile ); + CORBA::Object_var subShapeObject = SObjectToObject( subShapeSO ); + if ( !CORBA::is_nil( subShapeObject ) ) { + aSubShape = GEOM::GEOM_Shape::_narrow( subShapeObject ); + if ( !aSubShape->_is_nil() ) + aSubMesh = SMESH::SMESH_subMesh::_duplicate + ( myNewMeshImpl->createSubMesh( aSubShape ) ); + if ( aSubMesh->_is_nil() ) + continue; + string iorSubString = GetORB()->object_to_string( aSubMesh ); + int newSubId = myStudyContext->findId( iorSubString ); + myStudyContext->mapOldToNew( subid, newSubId ); + } + } + } + + if ( aSubMesh->_is_nil() ) + continue; + + // VSR: Get submesh data from MED convertor +// int anInternalSubmeshId = aSubMesh->GetId(); // this is not a persistent ID, it's an internal one computed from sub-shape +// if (myNewMeshImpl->_mapSubMesh.find(anInternalSubmeshId) != myNewMeshImpl->_mapSubMesh.end()) { +// MESSAGE("VSR - SMESH_Gen_i::Load(): loading from MED file submesh with ID = " << +// subid << " for subshape # " << anInternalSubmeshId); +// SMESHDS_SubMesh* aSubMeshDS = +// myNewMeshImpl->_mapSubMesh[anInternalSubmeshId]->CreateSubMeshDS(); +// if ( !aSubMeshDS ) { +// MESSAGE("VSR - SMESH_Gen_i::Load(): FAILED to create a submesh for subshape # " << +// anInternalSubmeshId << " in current mesh!"); +// } +// else +// myReader.GetSubMesh( aSubMeshDS, subid ); +// } + + // try to get applied hypotheses + if ( aSubGroup->ExistInternalObject( "Applied Hypotheses" ) ) { + // open "applied hypotheses" HDF group + aSubSubGroup = new HDFgroup( "Applied Hypotheses", aSubGroup ); + aSubSubGroup->OpenOnDisk(); + // get number of applied hypotheses + int aNbSubObjects = aSubSubGroup->nInternalObjects(); + for ( int l = 0; l < aNbSubObjects; l++ ) { + char name_dataset[ HDF_NAME_MAX_LEN+1 ]; + aSubSubGroup->InternalObjectIndentify( l, name_dataset ); + // check if it is a hypothesis + if ( string( name_dataset ).substr( 0, 3 ) == string( "Hyp" ) ) { + aDataset = new HDFdataset( name_dataset, aSubSubGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* refFromFile = new char[ size ]; + aDataset->ReadFromDisk( refFromFile ); + aDataset->CloseOnDisk(); + + //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile ); + //CORBA::Object_var hypObject = SObjectToObject( hypSO ); + int id = atoi( refFromFile ); + string anIOR = myStudyContext->getIORbyOldId( id ); + if ( !anIOR.empty() ) { + CORBA::Object_var hypObject = GetORB()->string_to_object( anIOR.c_str() ); + if ( !CORBA::is_nil( hypObject ) ) { + SMESH::SMESH_Hypothesis_var anHyp = SMESH::SMESH_Hypothesis::_narrow( hypObject ); + if ( !anHyp->_is_nil() && !aShape->_is_nil() ) + myNewMeshImpl->addHypothesis( aSubShape, anHyp ); + } } + } + } + // close "applied hypotheses" HDF group + aSubSubGroup->CloseOnDisk(); + } + + // try to get applied algorithms + if ( aSubGroup->ExistInternalObject( "Applied Algorithms" ) ) { + // open "applied algorithms" HDF group + aSubSubGroup = new HDFgroup( "Applied Algorithms", aSubGroup ); + aSubSubGroup->OpenOnDisk(); + // get number of applied algorithms + int aNbSubObjects = aSubSubGroup->nInternalObjects(); + for ( int l = 0; l < aNbSubObjects; l++ ) { + char name_dataset[ HDF_NAME_MAX_LEN+1 ]; + aSubSubGroup->InternalObjectIndentify( l, name_dataset ); + // check if it is an algorithm + if ( string( name_dataset ).substr( 0, 4 ) == string( "Algo" ) ) { + aDataset = new HDFdataset( name_dataset, aSubSubGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* refFromFile = new char[ size ]; + aDataset->ReadFromDisk( refFromFile ); + aDataset->CloseOnDisk(); + + //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile ); + //CORBA::Object_var hypObject = SObjectToObject( hypSO ); + int id = atoi( refFromFile ); + string anIOR = myStudyContext->getIORbyOldId( id ); + if ( !anIOR.empty() ) { + CORBA::Object_var hypObject = GetORB()->string_to_object( anIOR.c_str() ); + if ( !CORBA::is_nil( hypObject ) ) { + SMESH::SMESH_Hypothesis_var anHyp = SMESH::SMESH_Hypothesis::_narrow( hypObject ); + if ( !anHyp->_is_nil() && !aShape->_is_nil() ) + myNewMeshImpl->addHypothesis( aSubShape, anHyp ); + } + } + } + } + // close "applied algorithms" HDF group + aSubSubGroup->CloseOnDisk(); + } + + // close submesh HDF group + aSubGroup->CloseOnDisk(); + } + } + // close submeshes containers HDF group + aGroup->CloseOnDisk(); + } + } + + if(hasData){ + // Read sub-meshes from MED + MESSAGE("JFA - Create all sub-meshes"); + myReader.CreateAllSubMeshes(); + } + + // Recompute State (as computed sub-meshes are restored from MED) + if ( !aShape->_is_nil() ) { + MESSAGE("JFA - Compute State Engine ..."); +// map::iterator anAllSubMeshes = myNewMeshImpl->_mapSubMesh.begin(); +// for (; anAllSubMeshes != myNewMeshImpl->_mapSubMesh.end(); anAllSubMeshes++) +// { +// (*anAllSubMeshes).second->GetSubMeshDS(); // init SMESH_subMesh::_meshDS +// (*anAllSubMeshes).second->ComputeStateEngine(SMESH_subMesh::SUBMESH_RESTORED); +// } + TopoDS_Shape myLocShape = GetShapeReader()->GetShape( GetGeomEngine(), aShape ); + myNewMeshImpl->GetImpl().GetSubMesh(myLocShape)->ComputeStateEngine(SMESH_subMesh::SUBMESH_RESTORED); + MESSAGE("JFA - Compute State Engine finished"); + } + + // try to get groups + for ( int ii = GetNodeGroupsTag(); ii <= GetVolumeGroupsTag(); ii++ ) { + char name_group[ 30 ]; + if ( ii == GetNodeGroupsTag() ) + strcpy( name_group, "Groups of Nodes" ); + else if ( ii == GetEdgeGroupsTag() ) + strcpy( name_group, "Groups of Edges" ); + else if ( ii == GetFaceGroupsTag() ) + strcpy( name_group, "Groups of Faces" ); + else if ( ii == GetVolumeGroupsTag() ) + strcpy( name_group, "Groups of Volumes" ); + + if ( aTopGroup->ExistInternalObject( name_group ) ) { + aGroup = new HDFgroup( name_group, aTopGroup ); + aGroup->OpenOnDisk(); + // get number of groups + int aNbSubObjects = aGroup->nInternalObjects(); + for ( int j = 0; j < aNbSubObjects; j++ ) { + char name_dataset[ HDF_NAME_MAX_LEN+1 ]; + aGroup->InternalObjectIndentify( j, name_dataset ); + // check if it is an group + if ( string( name_dataset ).substr( 0, 5 ) == string( "Group" ) ) { + // --> get group id + int subid = atoi( string( name_dataset ).substr( 5 ).c_str() ); + if ( subid <= 0 ) + continue; + aDataset = new HDFdataset( name_dataset, aGroup ); + aDataset->OpenOnDisk(); + + // Retrieve actual group name + size = aDataset->GetSize(); + char* nameFromFile = new char[ size ]; + aDataset->ReadFromDisk( nameFromFile ); + aDataset->CloseOnDisk(); + + // Create group servant + SMESH::SMESH_Group_var aNewGroup = SMESH::SMESH_Group::_duplicate + ( myNewMeshImpl->createGroup( (SMESH::ElementType)(ii - GetNodeGroupsTag() + 1), + nameFromFile ) ); + // Obtain a SMESHDS_Group object + if ( aNewGroup->_is_nil() ) + continue; + + string iorSubString = GetORB()->object_to_string( aNewGroup ); + int newSubId = myStudyContext->findId( iorSubString ); + myStudyContext->mapOldToNew( subid, newSubId ); + + SMESH_Group_i* aGroupImpl = dynamic_cast( GetServant( aNewGroup ).in() ); + if ( !aGroupImpl ) + continue; + + SMESH_Group* aLocalGroup = myLocMesh.GetGroup( aGroupImpl->GetLocalID() ); + if ( !aLocalGroup ) + continue; + + SMESHDS_Group* aGroupDS = aLocalGroup->GetGroupDS(); + aGroupDS->SetStoreName( name_dataset ); + + // Fill group with contents from MED file + myReader.GetGroup( aGroupDS ); } + } + aGroup->CloseOnDisk(); + } + } } + // close mesh group + aTopGroup->CloseOnDisk(); + } + } + } + // close HDF file + aFile->CloseOnDisk(); + delete aFile; + + // Remove temporary files created from the stream + if ( !isMultiFile ) + SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true ); + + INFOS( "SMESH_Gen_i::Load completed" ); + return true; } //============================================================================= /*! - * + * SMESH_Gen_i::LoadASCII + * + * Load SMESH module's data in ASCII format (not implemented yet) */ //============================================================================= -char *SMESH_Gen_i::ComponentDataType() -{ - MESSAGE("SMESH_Gen_i::ComponentDataType"); - return strdup("SMESH"); +bool SMESH_Gen_i::LoadASCII( SALOMEDS::SComponent_ptr theComponent, + const SALOMEDS::TMPFile& theStream, + const char* theURL, + bool isMultiFile ) { + MESSAGE( "SMESH_Gen_i::LoadASCII" ); + return Load( theComponent, theStream, theURL, isMultiFile ); } //============================================================================= /*! - * + * SMESH_Gen_i::Close + * + * Clears study-connected data when it is closed */ //============================================================================= -char *SMESH_Gen_i::IORToLocalPersistentID(SALOMEDS::SObject_ptr theSObject, - const char *IORString, CORBA::Boolean isMultiFile, CORBA::Boolean isASCII) +void SMESH_Gen_i::Close( SALOMEDS::SComponent_ptr theComponent ) { - MESSAGE("SMESH_Gen_i::IORToLocalPersistentID"); + MESSAGE( "SMESH_Gen_i::Close" ); + + // Clear study contexts data + int studyId = myCurrentStudy->StudyId(); + if ( myStudyContextMap.find( studyId ) != myStudyContextMap.end() ) { + delete myStudyContextMap[ studyId ]; + myStudyContextMap.erase( studyId ); + } + return; +} - char objectId[10]; +//============================================================================= +/*! + * SMESH_Gen_i::ComponentDataType + * + * Get component data type + */ +//============================================================================= - SMESH::SMESH_Algo_var myAlgo = - SMESH::SMESH_Algo::_narrow(_orb->string_to_object(IORString)); - if (!CORBA::is_nil(myAlgo)) - { - string prefix = "Hypo_"; - sprintf(objectId, "%ld", myAlgo->GetId()); - string lpID = prefix + string(objectId); - return CORBA::string_dup(lpID.c_str()); - } - else - { - SMESH::SMESH_Hypothesis_var myHypo = - SMESH::SMESH_Hypothesis::_narrow(_orb->string_to_object(IORString)); - if (!CORBA::is_nil(myHypo)) - { - string prefix = "Hypo_"; - sprintf(objectId, "%ld", myHypo->GetId()); - string lpID = prefix + string(objectId); - return CORBA::string_dup(lpID.c_str()); - } - else - { - SMESH::SMESH_Mesh_var myMesh = - SMESH::SMESH_Mesh::_narrow(_orb->string_to_object(IORString)); - if (!CORBA::is_nil(myMesh)) - { - string prefix = "Mesh_"; - sprintf(objectId, "%ld", myMesh->GetId()); - string lpID = prefix + string(objectId); - return CORBA::string_dup(lpID.c_str()); - } - else - { - SMESH::SMESH_subMesh_var mySubMesh = - SMESH::SMESH_subMesh::_narrow(_orb-> - string_to_object(IORString)); - if (!CORBA::is_nil(mySubMesh)) - { - string prefix = "SubMesh_"; - sprintf(objectId, "%ld", mySubMesh->GetId()); - string lpID = prefix + string(objectId); - return CORBA::string_dup(lpID.c_str()); - } - else - return (strdup("no object")); - } - } - } +char* SMESH_Gen_i::ComponentDataType() +{ + MESSAGE( "SMESH_Gen_i::ComponentDataType" ); + return strdup( "SMESH" ); } + //============================================================================= /*! + * SMESH_Gen_i::IORToLocalPersistentID * + * Transform data from transient form to persistent */ //============================================================================= -char *SMESH_Gen_i::LocalPersistentIDToIOR(SALOMEDS::SObject_ptr theSObject, - const char *aLocalPersistentID, - CORBA::Boolean isMultiFile, CORBA::Boolean isASCII) +char* SMESH_Gen_i::IORToLocalPersistentID( SALOMEDS::SObject_ptr theSObject, + const char* IORString, + CORBA::Boolean isMultiFile, + CORBA::Boolean isASCII ) { - MESSAGE("SMESH_Gen_i::LocalPersistentIDToIOR"); - SCRUTE(aLocalPersistentID); - string clef = string(aLocalPersistentID); - SCRUTE(_SMESHCorbaObj[clef].c_str()); - return CORBA::string_dup(_SMESHCorbaObj[clef].c_str()); + MESSAGE( "SMESH_Gen_i::IORToLocalPersistentID" ); + StudyContext* myStudyContext = GetCurrentStudyContext(); + + if ( strcmp( IORString, "" ) != 0 ) { + int anId = myStudyContext->findId( IORString ); + if ( anId ) { + MESSAGE( "VSR " << anId ) + char strId[ 20 ]; + sprintf( strId, "%d", anId ); + return CORBA::string_dup( strId ); + } + } + return strdup( "" ); } //============================================================================= /*! - * + * SMESH_Gen_i::LocalPersistentIDToIOR + * + * Transform data from persistent form to transient */ //============================================================================= -SMESH_topo *SMESH_Gen_i::ExploreMainShape(GEOM::GEOM_Gen_ptr geomEngine, - CORBA::Long studyId, GEOM::GEOM_Shape_ptr aShape) +char* SMESH_Gen_i::LocalPersistentIDToIOR( SALOMEDS::SObject_ptr theSObject, + const char* aLocalPersistentID, + CORBA::Boolean isMultiFile, + CORBA::Boolean isASCII ) { - MESSAGE("SMESH_Mesh_i::ExploreMainShape"); - // _narrow() duplicates the reference and check the type - GEOM::GEOM_Gen_var geom = GEOM::GEOM_Gen::_narrow(geomEngine); - GEOM::GEOM_Shape_var myShape = GEOM::GEOM_Shape::_narrow(aShape); - - if (CORBA::is_nil(geom)) - THROW_SALOME_CORBA_EXCEPTION("bad geom reference", SALOME::BAD_PARAM); - if (CORBA::is_nil(myShape)) - THROW_SALOME_CORBA_EXCEPTION("bad shape reference", SALOME::BAD_PARAM); - MESSAGE("---"); - SCRUTE(myShape->Name()); - geom->GetCurrentStudy(studyId); - SCRUTE(studyId); - TopoDS_Shape mainShape = _ShapeReader->GetShape(geom, myShape); - MESSAGE("---"); - - // create an SMESH_topo object for the mainShape - - SMESH_topo *myTopo = new SMESH_topo(); - MESSAGE("---"); - - // explore local TopoDS_Shape, store reference of local TopoDS subShapes - - for (TopExp_Explorer exp(mainShape, TopAbs_COMPOUND); exp.More(); - exp.Next()) - { - const TopoDS_Compound & E = TopoDS::Compound(exp.Current()); - int i = myTopo->_myShapes[TopAbs_COMPOUND].Add(E); - SCRUTE(i); - } - for (TopExp_Explorer exp(mainShape, TopAbs_COMPSOLID); exp.More(); - exp.Next()) - { - const TopoDS_CompSolid & E = TopoDS::CompSolid(exp.Current()); - int i = myTopo->_myShapes[TopAbs_COMPSOLID].Add(E); - SCRUTE(i); - } - for (TopExp_Explorer exp(mainShape, TopAbs_SOLID); exp.More(); exp.Next()) - { - const TopoDS_Solid & E = TopoDS::Solid(exp.Current()); - int i = myTopo->_myShapes[TopAbs_SOLID].Add(E); - SCRUTE(i); - } - for (TopExp_Explorer exp(mainShape, TopAbs_SHELL); exp.More(); exp.Next()) - { - const TopoDS_Shell & E = TopoDS::Shell(exp.Current()); - int i = myTopo->_myShapes[TopAbs_SHELL].Add(E); - SCRUTE(i); - } - for (TopExp_Explorer exp(mainShape, TopAbs_FACE); exp.More(); exp.Next()) - { - const TopoDS_Face & E = TopoDS::Face(exp.Current()); - int i = myTopo->_myShapes[TopAbs_FACE].Add(E); - SCRUTE(i); - } - for (TopExp_Explorer exp(mainShape, TopAbs_WIRE); exp.More(); exp.Next()) - { - const TopoDS_Wire & E = TopoDS::Wire(exp.Current()); - int i = myTopo->_myShapes[TopAbs_WIRE].Add(E); - SCRUTE(i); - } - for (TopExp_Explorer exp(mainShape, TopAbs_EDGE); exp.More(); exp.Next()) - { - const TopoDS_Edge & E = TopoDS::Edge(exp.Current()); - int i = myTopo->_myShapes[TopAbs_EDGE].Add(E); - SCRUTE(i); - } - for (TopExp_Explorer exp(mainShape, TopAbs_VERTEX); exp.More(); exp.Next()) - { - const TopoDS_Vertex & E = TopoDS::Vertex(exp.Current()); - int i = myTopo->_myShapes[TopAbs_VERTEX].Add(E); - SCRUTE(i); - } + MESSAGE( "SMESH_Gen_i::LocalPersistentIDToIOR(): id = " << aLocalPersistentID ); + StudyContext* myStudyContext = GetCurrentStudyContext(); + + if ( strcmp( aLocalPersistentID, "" ) != 0 ) { + int anId = atoi( aLocalPersistentID ); + return CORBA::string_dup( myStudyContext->getIORbyOldId( anId ).c_str() ); + } + return strdup( "" ); +} - // explore subShapes of distant CORBA object, - // associate distant CORBA subShape references - // with local reference to local TopoDS subShape +//============================================================================= +/*! + * SMESH_Gen_i::CanPublishInStudy + * + * Returns true if object can be published in the study + */ +//============================================================================= - string filenode = "toposhape.txt"; - ofstream fic(filenode.c_str()); +bool SMESH_Gen_i::CanPublishInStudy(CORBA::Object_ptr theIOR) +{ + SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(theIOR); + if( !aMesh->_is_nil() ) + return true; - for (int shapeType = TopAbs_COMPOUND; shapeType < TopAbs_SHAPE; shapeType++) - { - fic << "shape type : " << SMESH_shapeTypeNames[shapeType]; - - GEOM::GEOM_Gen::ListOfGeomShapes_var subShapes - = geom->SubShapeAll(myShape, shapeType); - int nbSubShapes = subShapes->length(); - int nbLocal = myTopo->_myShapes[shapeType].Extent(); - fic << " - number of elements: " << nbSubShapes << endl; - ASSERT(nbSubShapes == nbLocal); - - for (int i = 0; i < nbSubShapes; i++) - { - GEOM::GEOM_Shape_var aSubShape = subShapes[i]; - string idShape = SMESH_topo::GetShapeLocalId(aSubShape); - fic << " " << idShape; - SCRUTE(idShape); - TopoDS_Shape aLocShape = _ShapeReader->GetShape(geom, aSubShape); - for (int j = 1; j <= nbLocal; j++) - if (aLocShape.IsSame(myTopo->_myShapes[shapeType].FindKey(j))) - { - MESSAGE(" --- trouve = " << j); - myTopo->_mapIndShapes[shapeType][idShape] = j; - fic << " --- trouve = " << j; - break; - } - fic << endl; - } - } - fic.close(); + SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(theIOR); + if( !aSubMesh->_is_nil() ) + return true; + + SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow(theIOR); + if( !aHyp->_is_nil() ) + return true; - return myTopo; + SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow(theIOR); + if( !aGroup->_is_nil() ) + return true; + + return false; } -/** - * Import a mesh from a file - * @param fileName file name to be imported - * @param fileType Currently it could be either "DAT", "UNV" or "MED". +//============================================================================= +/*! + * SMESH_Gen_i::PublishInStudy + * + * Publish object in the study */ -SMESH::SMESH_Mesh_ptr SMESH_Gen_i::Import(CORBA::Long studyId, - const char *fileName, const char *fileType) -{ - MESSAGE("SMESH_Gen_I::Import"); - SMESH_Mesh_i *meshServant; - try - { - if (_mapStudyContext_i.find(studyId) == _mapStudyContext_i.end()) - { - _mapStudyContext_i[studyId] = new StudyContext_iStruct; - } - StudyContext_iStruct *myStudyContext = _mapStudyContext_i[studyId]; +//============================================================================= - // create a new mesh object - SMESH_Mesh * meshImpl=_impl.Import(studyId, fileName, fileType); - - // create a new mesh object servant, store it in a map in study context - meshServant = new SMESH_Mesh_i(this, NULL, studyId, meshImpl); - myStudyContext->mapMesh_i[meshImpl->GetId()] = meshServant; +SALOMEDS::SObject_ptr SMESH_Gen_i::PublishInStudy(SALOMEDS::Study_ptr theStudy, + SALOMEDS::SObject_ptr theSObject, + CORBA::Object_ptr theIOR, + const char* theName) +throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + MESSAGE( "********** SMESH_Gen_i::PublishInStudy()" ); + SALOMEDS::SObject_var aSO; + + // san - first try to find SObject corresponding to SMESH component in theStudy + // It is dangerous to use FindComponent("MESH") for this, as some other component + // of type "MESH" might be present in theStudy. + // So component's user name obtained from ModuleCatalog is passed to FindObject()... + SALOME_ModuleCatalog::ModuleCatalog_var aCat = + SALOME_ModuleCatalog::ModuleCatalog::_narrow( GetNS()->Resolve("/Kernel/ModulCatalog") ); + if ( CORBA::is_nil( aCat ) ) + return aSO._retn(); + + SALOME_ModuleCatalog::Acomponent_var aComp = aCat->GetComponent( "SMESH" ); + if ( CORBA::is_nil( aComp ) ) + return aSO._retn(); + + SALOMEDS::SComponent_var father = + SALOMEDS::SComponent::_narrow( theStudy->FindObject( strdup( aComp->componentusername() ) ) ); + SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder(); + + SALOMEDS::GenericAttribute_var anAttr; + SALOMEDS::AttributeName_var aName; + SALOMEDS::AttributePixMap_var aPixmap; + + if ( father->_is_nil() ) { + father = aStudyBuilder->NewComponent( "MESH" ); + anAttr = aStudyBuilder->FindOrCreateAttribute( father, "AttributeName" ); + aName = SALOMEDS::AttributeName::_narrow( anAttr ); + aName ->SetValue( strdup( aComp->componentusername() ) ); + anAttr = aStudyBuilder->FindOrCreateAttribute( father, "AttributePixMap" ); + aPixmap = SALOMEDS::AttributePixMap::_narrow( anAttr ); + aPixmap ->SetPixMap( "ICON_OBJBROWSER_SMESH" ); + aStudyBuilder->DefineComponentInstance( father, SMESH_Gen::_this() ); + } + + if ( father->_is_nil() ) + return aSO._retn(); + + SALOMEDS::AttributeIOR_var anIOR; + SALOMEDS::AttributeSelectable_var aSelAttr; + TCollection_AsciiString anObjName("obj"); + + // Publishing a mesh + SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( theIOR ); + if( !aMesh->_is_nil() ) { + // Find correct free tag + long aTag = FindMaxChildTag( father.in() ); + if ( aTag <= GetAlgorithmsRootTag() ) + aTag = GetAlgorithmsRootTag() + 1; + else + aTag++; + // Add New Mesh + SALOMEDS::SObject_var newMesh = aStudyBuilder->NewObjectToTag( father, aTag ); + anAttr = aStudyBuilder->FindOrCreateAttribute( newMesh, "AttributePixMap" ); + aPixmap = SALOMEDS::AttributePixMap::_narrow( anAttr ); + aPixmap ->SetPixMap( "ICON_SMESH_TREE_MESH" ); + anAttr = aStudyBuilder->FindOrCreateAttribute( newMesh, "AttributeIOR" ); + anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + anIOR ->SetValue( GetORB()->object_to_string( aMesh ) ); + aSO = SALOMEDS::SObject::_narrow( newMesh ); + anObjName = TCollection_AsciiString( "Mesh" ); + } + + // Publishing a sub-mesh + SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( theIOR ); + if( aSO->_is_nil() && !aSubMesh->_is_nil() ) { + // try to obtain a parent mesh's SObject + MESSAGE( "********** SMESH_Gen_i::PublishInStudy(): publishing submesh..." ); + SALOMEDS::SObject_var aParentSO; + SMESH::SMESH_Mesh_var aParentMesh; + SMESH_subMesh_i* aServant = dynamic_cast( GetServant( aSubMesh ).in() ); + if ( aServant != NULL ) { + aParentMesh = aServant->_mesh_i->_this(); + if ( !aParentMesh->_is_nil() ) { + aParentSO = theStudy->FindObjectIOR( GetORB()->object_to_string( aParentMesh ) ); + } + } + + // Find submesh sub-tree tag + if ( !aParentSO->_is_nil() ) { + long aRootTag = GetSubMeshOnVertexTag(); + char* aRootName = ""; + + SMESH_Mesh_i* aMeshServant = aServant->_mesh_i; + if ( aMeshServant->_mapSubMesh.find( aServant->GetId() ) != aMeshServant->_mapSubMesh.end() ) { + MESSAGE( "********** SMESH_Gen_i::PublishInStudy(): local submesh found" ) + SMESH_subMesh* aLocalSubMesh = aMeshServant->_mapSubMesh[aServant->GetId()]; + switch ( aLocalSubMesh->GetSubShape().ShapeType() ) { + case TopAbs_VERTEX: + aRootTag = GetSubMeshOnVertexTag(); + aRootName = "SubMeshes on Vertex"; + break; + case TopAbs_EDGE: + aRootTag = GetSubMeshOnEdgeTag(); + aRootName = "SubMeshes on Edge"; + break; + case TopAbs_FACE: + aRootTag = GetSubMeshOnFaceTag(); + aRootName = "SubMeshes on Face"; + break; + case TopAbs_SOLID: + aRootTag = GetSubMeshOnSolidTag(); + aRootName = "SubMeshes on Solid"; + break; + default: + aRootTag = GetSubMeshOnCompoundTag(); + aRootName = "SubMeshes on Compound"; + break; } - catch(SALOME_Exception & S_ex) - { - THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); + } + + // Find or create submesh root + SALOMEDS::SObject_var aRootSO; + if ( !aParentSO->FindSubObject ( aRootTag, aRootSO ) ) { + MESSAGE( "********** SMESH_Gen_i::PublishInStudy(): creating submesh root..." ) + aRootSO = aStudyBuilder->NewObjectToTag( aParentSO, aRootTag ); + anAttr = aStudyBuilder->FindOrCreateAttribute( aRootSO, "AttributeName" ); + aName = SALOMEDS::AttributeName::_narrow( anAttr ); + aName ->SetValue( aRootName ); + anAttr = aStudyBuilder->FindOrCreateAttribute( aRootSO, "AttributeSelectable" ); + aSelAttr = SALOMEDS::AttributeSelectable::_narrow( anAttr ); + aSelAttr ->SetSelectable( false ); + } + + // Add new submesh to corresponding sub-tree + MESSAGE( "********** SMESH_Gen_i::PublishInStudy(): adding submesh to study..." ) + SALOMEDS::SObject_var newMesh = aStudyBuilder->NewObject( aRootSO ); + anAttr = aStudyBuilder->FindOrCreateAttribute( newMesh, "AttributePixMap" ); + aPixmap = SALOMEDS::AttributePixMap::_narrow( anAttr ); + aPixmap ->SetPixMap( "ICON_SMESH_TREE_MESH" ); + anAttr = aStudyBuilder->FindOrCreateAttribute( newMesh, "AttributeIOR" ); + anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + anIOR ->SetValue( GetORB()->object_to_string( aSubMesh ) ); + aSO = SALOMEDS::SObject::_narrow( newMesh ); + anObjName = TCollection_AsciiString( "SubMesh" ); + } + } + + // Publishing a hypothesis or algorithm + SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( theIOR ); + if( aSO->_is_nil() && !aHyp->_is_nil() ) { + //Find or Create Hypothesis root + SALOMEDS::SObject_var HypothesisRoot; + Standard_Integer aRootTag = + SMESH::SMESH_Algo::_narrow( theIOR )->_is_nil() ? GetHypothesisRootTag() : GetAlgorithmsRootTag(); + + if ( !father->FindSubObject ( aRootTag, HypothesisRoot ) ) { + HypothesisRoot = aStudyBuilder->NewObjectToTag( father, aRootTag ); + anAttr = aStudyBuilder->FindOrCreateAttribute( HypothesisRoot, "AttributeName" ); + aName = SALOMEDS::AttributeName::_narrow( anAttr ); + aName ->SetValue( aRootTag == GetHypothesisRootTag() ? "Hypotheses" : "Algorithms" ); + anAttr = aStudyBuilder->FindOrCreateAttribute( HypothesisRoot, "AttributeSelectable" ); + aSelAttr = SALOMEDS::AttributeSelectable::_narrow( anAttr ); + aSelAttr ->SetSelectable( false ); + anAttr = aStudyBuilder->FindOrCreateAttribute( HypothesisRoot, "AttributePixMap" ); + aPixmap = SALOMEDS::AttributePixMap::_narrow( anAttr ); + aPixmap ->SetPixMap( aRootTag == GetHypothesisRootTag() ? "ICON_SMESH_TREE_HYPO" : "ICON_SMESH_TREE_ALGO" ); + } + + // Add New Hypothesis + string aPmName; + SALOMEDS::SObject_var newHypo = aStudyBuilder->NewObject( HypothesisRoot ); + anAttr = aStudyBuilder->FindOrCreateAttribute( newHypo, "AttributePixMap" ); + aPixmap = SALOMEDS::AttributePixMap::_narrow( anAttr ); + aPmName = ( aRootTag == GetHypothesisRootTag() ? "ICON_SMESH_TREE_HYPO_" : "ICON_SMESH_TREE_ALGO_" ); + aPmName += aHyp->GetName(); + aPixmap ->SetPixMap( aPmName.c_str() ); + anAttr = aStudyBuilder->FindOrCreateAttribute( newHypo, "AttributeIOR" ); + anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + anIOR ->SetValue( GetORB()->object_to_string( aHyp ) ); + aSO = SALOMEDS::SObject::_narrow( newHypo ); + anObjName = TCollection_AsciiString( aHyp->GetName() ); + } + + // Publishing a group + SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow(theIOR); + if( aSO->_is_nil() && !aGroup->_is_nil() ) { + // try to obtain a parent mesh's SObject + MESSAGE( "********** SMESH_Gen_i::PublishInStudy(): publishing group..." ); + SALOMEDS::SObject_var aParentSO; + SMESH::SMESH_Mesh_var aParentMesh; + SMESH_Group_i* aServant = dynamic_cast( GetServant( aGroup ).in() ); + if ( aServant != NULL ) { + aParentMesh = SMESH::SMESH_Mesh::_narrow( GetPOA()->servant_to_reference( aServant->GetMeshServant() ) ); + if ( !aParentMesh->_is_nil() ) { + MESSAGE( "********** SMESH_Gen_i::PublishInStudy(): publishing group: refernce to mesh is OK" ); + string anIOR = GetORB()->object_to_string( aParentMesh ); + MESSAGE( "********** SMESH_Gen_i::PublishInStudy(): publishing group: mesh IOR = "<FindObjectIOR( anIOR.c_str() ); + } + } + + // Find proper group sub-tree tag + if ( !aParentSO->_is_nil() ) { + MESSAGE( "********** SMESH_Gen_i::PublishInStudy(): publishing group: parent mesh found" ); + int aType = (int)aGroup->GetType(); + const char* aRootNames[] = { "Compound Groups", "Groups of Nodes", "Groups of Edges", "Groups of Faces", "Groups of Volumes" }; + + // Currently, groups with heterogenous content are not supported + if ( aType != SMESH::ALL ) { + MESSAGE( "********** SMESH_Gen_i::PublishInStudy(): publishing group: group type OK" ); + long aRootTag = GetNodeGroupsTag() + aType - 1; + + // Find or create groups root + SALOMEDS::SObject_var aRootSO; + if ( !aParentSO->FindSubObject ( aRootTag, aRootSO ) ) { + MESSAGE( "********** SMESH_Gen_i::PublishInStudy(): creating groups root..." ) + aRootSO = aStudyBuilder->NewObjectToTag( aParentSO, aRootTag ); + anAttr = aStudyBuilder->FindOrCreateAttribute( aRootSO, "AttributeName" ); + aName = SALOMEDS::AttributeName::_narrow( anAttr ); + aName ->SetValue( aRootNames[aType] ); + anAttr = aStudyBuilder->FindOrCreateAttribute( aRootSO, "AttributeSelectable" ); + aSelAttr = SALOMEDS::AttributeSelectable::_narrow( anAttr ); + aSelAttr ->SetSelectable( false ); } - // activate the CORBA servant of Mesh - - SMESH::SMESH_Mesh_var mesh - = SMESH::SMESH_Mesh::_narrow(meshServant->_this()); - - meshServant->SetIor(mesh); - return SMESH::SMESH_Mesh::_duplicate(mesh); + // Add new group to corresponding sub-tree + MESSAGE( "********** SMESH_Gen_i::PublishInStudy(): adding group to study..." ) + SALOMEDS::SObject_var aGroupSO = aStudyBuilder->NewObject( aRootSO ); + anAttr = aStudyBuilder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" ); + aPixmap = SALOMEDS::AttributePixMap::_narrow( anAttr ); + aPixmap ->SetPixMap( "ICON_SMESH_TREE_GROUP" ); + anAttr = aStudyBuilder->FindOrCreateAttribute( aGroupSO, "AttributeIOR" ); + anIOR = SALOMEDS::AttributeIOR::_narrow( anAttr ); + anIOR ->SetValue( GetORB()->object_to_string( aGroup ) ); + aSO = SALOMEDS::SObject::_narrow( aGroupSO ); + anObjName = TCollection_AsciiString( "Group" ); + } + } + } + + // Setting SObject's name + if ( !aSO->_is_nil() ) { + if ( strlen( theName ) == 0 ) + anObjName += TCollection_AsciiString( "_" ) + TCollection_AsciiString( aSO->Tag() ); + else + anObjName = TCollection_AsciiString( strdup( theName ) ); + anAttr = aStudyBuilder->FindOrCreateAttribute( aSO, "AttributeName" ); + aName = SALOMEDS::AttributeName::_narrow( anAttr ); + aName ->SetValue( anObjName.ToCString() ); + } + + MESSAGE( "********** SMESH_Gen_i::PublishInStudy(): COMPLETED" ) + return aSO._retn(); } - + //============================================================================= /*! - * C factory, accessible with dlsym, after dlopen + * SMESHEngine_factory + * + * C factory, accessible with dlsym, after dlopen */ //============================================================================= extern "C" { - PortableServer::ObjectId * SMESHEngine_factory(CORBA::ORB_ptr orb, - PortableServer::POA_ptr poa, - PortableServer::ObjectId * contId, - const char *instanceName, const char *interfaceName) - { - MESSAGE("PortableServer::ObjectId * SMESHEngine_factory()"); - SCRUTE(interfaceName); - SMESH_Gen_i *mySMESH_Gen - = new SMESH_Gen_i(orb, poa, contId, instanceName, interfaceName); - return mySMESH_Gen->getId(); - } + PortableServer::ObjectId* SMESHEngine_factory( CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + PortableServer::ObjectId* contId, + const char* instanceName, + const char* interfaceName ) + { + MESSAGE( "PortableServer::ObjectId* SMESHEngine_factory()" ); + SCRUTE(interfaceName); + SMESH_Gen_i * mySMESH_Gen + = new SMESH_Gen_i(orb, poa, contId, instanceName, interfaceName); + return mySMESH_Gen->getId() ; + } } diff --git a/src/SMESH_I/SMESH_Gen_i.hxx b/src/SMESH_I/SMESH_Gen_i.hxx index 7a22deae3..77e3adf43 100644 --- a/src/SMESH_I/SMESH_Gen_i.hxx +++ b/src/SMESH_I/SMESH_Gen_i.hxx @@ -38,11 +38,8 @@ #include CORBA_CLIENT_HEADER(SALOMEDS) #include CORBA_CLIENT_HEADER(SALOMEDS_Attributes) - -class SMESH_Mesh_i; - -#include "SMESH_HypothesisFactory_i.hxx" #include "SMESH_Mesh_i.hxx" +#include "SMESH_Hypothesis_i.hxx" #include "SALOME_Component_i.hxx" #include "SALOME_NamingService.hxx" @@ -50,140 +47,268 @@ class SMESH_Mesh_i; #include "SMESH_topo.hxx" #include "GEOM_Client.hxx" -#include - #include -typedef struct studyContext_iStruct +class SMESH_Mesh_i; +class SALOME_LifeCycleCORBA; + +// =========================================================== +// Study context - stores study-connected objects references +// ========================================================== +class StudyContext { - map mapMesh_i; -} StudyContext_iStruct; +public: + // constructor + StudyContext() {} + // destructor + ~StudyContext() + { + mapIdToIOR.clear(); + mapIdToId.clear(); + } + // register object in the internal map and return its id + int addObject( string theIOR ) + { + int nextId = getNextId(); + mapIdToIOR[ nextId ] = theIOR; + return nextId; + } + // find the object id in the internal map by the IOR + int findId( string theIOR ) + { + map::iterator imap; + for ( imap = mapIdToIOR.begin(); imap != mapIdToIOR.end(); ++imap ) { + if ( imap->second == theIOR ) + return imap->first; + } + return 0; + } + // get object's IOR by id + string getIORbyId( const int theId ) + { + if ( mapIdToIOR.find( theId ) != mapIdToIOR.end() ) + return mapIdToIOR[ theId ]; + return string( "" ); + } + // get object's IOR by old id + string getIORbyOldId( const int theOldId ) + { + if ( mapIdToId.find( theOldId ) != mapIdToId.end() ) + return getIORbyId( mapIdToId[ theOldId ] ); + return string( "" ); + } + // maps old object id to the new one (used when restoring data) + void mapOldToNew( const int oldId, const int newId ) { + mapIdToId[ oldId ] = newId; + } + +private: + // get next free object identifier + int getNextId() + { + int id = 1; + while( mapIdToIOR.find( id ) != mapIdToIOR.end() ) + id++; + return id; + } + + map mapIdToIOR; // persistent-to-transient map + map mapIdToId; // used to translate object from persistent to transient form +}; +// =========================================================== +// SMESH module's engine +// ========================================================== class SMESH_Gen_i: - public POA_SMESH::SMESH_Gen, - public Engines_Component_i + public virtual POA_SMESH::SMESH_Gen, + public virtual Engines_Component_i { public: + // Get ORB object + static CORBA::ORB_var GetORB() { return myOrb;} + // Get SMESH module's POA object + static PortableServer::POA_var GetPOA() { return myPoa;} + // Get Naming Service object + static SALOME_NamingService* GetNS(); + // Get SALOME_LifeCycleCORBA object + static SALOME_LifeCycleCORBA* GetLCC(); + // Retrieve and get GEOM engine reference + static GEOM::GEOM_Gen_ptr GetGeomEngine(); + // Get object of the CORBA reference + static PortableServer::ServantBase_var GetServant( CORBA::Object_ptr theObject ); + // Get CORBA object corresponding to the SALOMEDS::SObject + static CORBA::Object_var SObjectToObject( SALOMEDS::SObject_ptr theSObject ); + // Default constructor SMESH_Gen_i(); - SMESH_Gen_i(CORBA::ORB_ptr orb, - PortableServer::POA_ptr poa, - PortableServer::ObjectId * contId, - const char *instanceName, - const char *interfaceName); + // Standard constructor + SMESH_Gen_i( CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + PortableServer::ObjectId* contId, + const char* instanceName, + const char* interfaceName ); + // Destructor virtual ~SMESH_Gen_i(); - SMESH::SMESH_Hypothesis_ptr CreateHypothesis(const char* anHyp, - CORBA::Long studyId) - throw (SALOME::SALOME_Exception); + // ***************************************** + // Interface methods + // ***************************************** + + // Set current study + void SetCurrentStudy( SALOMEDS::Study_ptr theStudy ); + // Get current study + SALOMEDS::Study_ptr GetCurrentStudy(); + + // Create hypothesis/algorothm of given type + SMESH::SMESH_Hypothesis_ptr CreateHypothesis (const char* theHypType, + const char* theLibName) + throw ( SALOME::SALOME_Exception ); + + // Create empty mesh on a shape + SMESH::SMESH_Mesh_ptr CreateMesh( GEOM::GEOM_Shape_ptr theShape ) + throw ( SALOME::SALOME_Exception ); + + // Create mesh(es) and import data from MED file + SMESH::mesh_array* CreateMeshesFromMED( const char* theFileName, + SMESH::DriverMED_ReadStatus& theStatus ) + throw ( SALOME::SALOME_Exception ); + + // Compute mesh on a shape + CORBA::Boolean Compute( SMESH::SMESH_Mesh_ptr theMesh, + GEOM::GEOM_Shape_ptr theShape ) + throw ( SALOME::SALOME_Exception ); + + // Returns true if mesh contains enough data to be computed + CORBA::Boolean IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh, + GEOM::GEOM_Shape_ptr theShape ) + throw ( SALOME::SALOME_Exception ); + + // Get sub-shapes unique ID's list + SMESH::long_array* GetSubShapesId( GEOM::GEOM_Shape_ptr theMainShape, + const SMESH::shape_array& theListOfSubShape ) + throw ( SALOME::SALOME_Exception ); + + + // **************************************************** + // Interface inherited methods (from SALOMEDS::Driver) + // **************************************************** + + // Save SMESH data + SALOMEDS::TMPFile* Save( SALOMEDS::SComponent_ptr theComponent, + const char* theURL, + bool isMultiFile ); + // Load SMESH data + bool Load( SALOMEDS::SComponent_ptr theComponent, + const SALOMEDS::TMPFile& theStream, + const char* theURL, + bool isMultiFile ); + // Save SMESH data in ASCII format + SALOMEDS::TMPFile* SaveASCII( SALOMEDS::SComponent_ptr theComponent, + const char* theURL, + bool isMultiFile ); + // Load SMESH data in ASCII format + bool LoadASCII( SALOMEDS::SComponent_ptr theComponent, + const SALOMEDS::TMPFile& theStream, + const char* theURL, + bool isMultiFile ); + + // Create filter manager + SMESH::FilterManager_ptr CreateFilterManager(); + + // Clears study-connected data when it is closed + void Close( SALOMEDS::SComponent_ptr theComponent ); - SMESH::SMESH_Mesh_ptr Init(GEOM::GEOM_Gen_ptr geomEngine, - CORBA::Long studyId, - GEOM::GEOM_Shape_ptr aShape) - throw (SALOME::SALOME_Exception); - - SMESH::SMESH_Mesh_ptr Init(GEOM::GEOM_Gen_ptr geomEngine, - CORBA::Long studyId, - GEOM::GEOM_Shape_ptr aShape, - int meshID) - throw (SALOME::SALOME_Exception); - - CORBA::Boolean Compute(SMESH::SMESH_Mesh_ptr aMesh, - GEOM::GEOM_Shape_ptr aShape) - throw (SALOME::SALOME_Exception); - - CORBA::Boolean IsReadyToCompute(SMESH::SMESH_Mesh_ptr aMesh, - GEOM::GEOM_Shape_ptr aShape) - throw (SALOME::SALOME_Exception); - - SMESH::long_array* GetSubShapesId(GEOM::GEOM_Gen_ptr geomEngine, - CORBA::Long studyId, - GEOM::GEOM_Shape_ptr mainShape, - const SMESH::shape_array& listOfSubShape) - throw (SALOME::SALOME_Exception); - - SMESH::SMESH_Mesh_ptr Import(CORBA::Long studyId, const char* fileName, - const char* fileType); - - // inherited methods from SALOMEDS::Driver - - SALOMEDS::TMPFile* Save(SALOMEDS::SComponent_ptr theComponent, - const char* theURL, - bool isMultiFile); - bool Load(SALOMEDS::SComponent_ptr theComponent, - const SALOMEDS::TMPFile& theStream, - const char* theURL, - bool isMultiFile); - - SALOMEDS::TMPFile* SaveASCII(SALOMEDS::SComponent_ptr theComponent, - const char* theURL, - bool isMultiFile); - bool LoadASCII(SALOMEDS::SComponent_ptr theComponent, - const SALOMEDS::TMPFile& theStream, - const char* theURL, - bool isMultiFile); - - void Close(SALOMEDS::SComponent_ptr theComponent); + // Get component data type char* ComponentDataType(); - char* IORToLocalPersistentID(SALOMEDS::SObject_ptr theSObject, - const char* IORString, - CORBA::Boolean isMultiFile, - CORBA::Boolean isASCII); - char* LocalPersistentIDToIOR(SALOMEDS::SObject_ptr theSObject, - const char* aLocalPersistentID, - CORBA::Boolean isMultiFile, - CORBA::Boolean isASCII); - - bool CanPublishInStudy(CORBA::Object_ptr theIOR) { return false; } - SALOMEDS::SObject_ptr PublishInStudy(SALOMEDS::Study_ptr theStudy, - SALOMEDS::SObject_ptr theSObject, - CORBA::Object_ptr theObject, - const char* theName) throw (SALOME::SALOME_Exception) { - SALOMEDS::SObject_var aResultSO; - return aResultSO._retn(); - } + // Transform data from transient form to persistent + char* IORToLocalPersistentID( SALOMEDS::SObject_ptr theSObject, + const char* IORString, + CORBA::Boolean isMultiFile, + CORBA::Boolean isASCII ); + // Transform data from persistent form to transient + char* LocalPersistentIDToIOR( SALOMEDS::SObject_ptr theSObject, + const char* aLocalPersistentID, + CORBA::Boolean isMultiFile, + CORBA::Boolean isASCII ); + + // Returns true if object can be published in the study + bool CanPublishInStudy( CORBA::Object_ptr theIOR ); + // Publish object in the study + SALOMEDS::SObject_ptr PublishInStudy( SALOMEDS::Study_ptr theStudy, + SALOMEDS::SObject_ptr theSObject, + CORBA::Object_ptr theObject, + const char* theName ) + throw ( SALOME::SALOME_Exception ); - CORBA::Boolean CanCopy(SALOMEDS::SObject_ptr theObject) {return false;} - SALOMEDS::TMPFile* CopyFrom(SALOMEDS::SObject_ptr theObject, CORBA::Long& theObjectID) {return false;} - CORBA::Boolean CanPaste(const char* theComponentName, CORBA::Long theObjectID) {return false;} - SALOMEDS::SObject_ptr PasteInto(const SALOMEDS::TMPFile& theStream, - CORBA::Long theObjectID, - SALOMEDS::SObject_ptr theObject) { + // Copy-paste methods - returns true if object can be copied to the clipboard + CORBA::Boolean CanCopy( SALOMEDS::SObject_ptr theObject ) { return false; } + // Copy-paste methods - copy object to the clipboard + SALOMEDS::TMPFile* CopyFrom( SALOMEDS::SObject_ptr theObject, CORBA::Long& theObjectID ) { return false; } + // Copy-paste methods - returns true if object can be pasted from the clipboard + CORBA::Boolean CanPaste( const char* theComponentName, CORBA::Long theObjectID ) { return false; } + // Copy-paste methods - paste object from the clipboard + SALOMEDS::SObject_ptr PasteInto( const SALOMEDS::TMPFile& theStream, + CORBA::Long theObjectID, + SALOMEDS::SObject_ptr theObject ) { SALOMEDS::SObject_var aResultSO; return aResultSO._retn(); } - GEOM_Client* _ShapeReader; -protected: - SMESH_topo* ExploreMainShape(GEOM::GEOM_Gen_ptr geomEngine, - CORBA::Long studyId, - GEOM::GEOM_Shape_ptr aShape); + // ***************************************** + // Internal methods + // ***************************************** +public: + // Get shape reader + GEOM_Client* GetShapeReader(); + + // Tags definition + static long GetHypothesisRootTag(); + static long GetAlgorithmsRootTag(); + static long GetRefOnShapeTag(); + static long GetRefOnAppliedHypothesisTag(); + static long GetRefOnAppliedAlgorithmsTag(); + static long GetSubMeshOnVertexTag(); + static long GetSubMeshOnEdgeTag(); + static long GetSubMeshOnFaceTag(); + static long GetSubMeshOnSolidTag(); + static long GetSubMeshOnCompoundTag(); + static long GetNodeGroupsTag(); + static long GetEdgeGroupsTag(); + static long GetFaceGroupsTag(); + static long GetVolumeGroupsTag(); + + // Get study context + StudyContext* GetCurrentStudyContext(); + +private: + // Create hypothesis of given type + SMESH::SMESH_Hypothesis_ptr createHypothesis( const char* theHypName, + const char* theLibName) + throw ( SALOME::SALOME_Exception ); + + // Create empty mesh on shape + SMESH::SMESH_Mesh_ptr createMesh() + throw ( SALOME::SALOME_Exception ); + + static void loadGeomData( SALOMEDS::SComponent_ptr theCompRoot ); private: - void loadMesh(char * name, HDFfile * hdf_file, char * meshFile, - SALOMEDS::Study_var study); - void loadHypothesis(char * name, HDFfile * hdf_file, char * hypothesisFile, - int studyId); - void loadAlgorithms(char * name, HDFfile * hdf_file, char * algorithmsFile, - int studyId); - void loadAppliedHypothesis(HDFgroup * hdfGroupMeshId, bool _found, - SALOMEDS::Study_var Study, SMESH::SMESH_Mesh_var myNewMesh, - GEOM::GEOM_Shape_var aShape); - GEOM::GEOM_Gen_var getGeomEngine(); - GEOM::GEOM_Shape_var getShape(SALOMEDS::Study_var Study, char * refFromFile); - -void loadAppliedAlgorithms(HDFgroup * hdfGroupMeshId, - bool _found, SALOMEDS::Study_var Study, SMESH::SMESH_Mesh_var myNewMesh, - GEOM::GEOM_Shape_var aShape); -void loadSubMeshes(HDFgroup * hdfGroupMeshId, char * msgname, - SALOMEDS::Study_var Study, SMESH::SMESH_Mesh_var myNewMesh); - - SMESH_HypothesisFactory_i _hypothesisFactory_i; - ::SMESH_Gen _impl; // no namespace here - - map _mapStudyContext_i; - map _SMESHCorbaObj; + + static CORBA::ORB_var myOrb; // ORB reference + static PortableServer::POA_var myPoa; // POA reference + static SALOME_NamingService* myNS; // Naming Service + static SALOME_LifeCycleCORBA* myLCC; // Life Cycle CORBA + + ::SMESH_Gen myGen; // SMESH_Gen local implementation + + // hypotheses managing + map myHypCreatorMap; + + map myStudyContextMap; // Map of study context objects + + GEOM_Client* myShapeReader; // Shape reader + SALOMEDS::Study_var myCurrentStudy; // Current study }; #endif diff --git a/src/SMESH_I/SMESH_Group_i.cxx b/src/SMESH_I/SMESH_Group_i.cxx new file mode 100644 index 000000000..81a495137 --- /dev/null +++ b/src/SMESH_I/SMESH_Group_i.cxx @@ -0,0 +1,358 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes +// +// Copyright (C) 2004 CEA +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_Group_i.cxx +// Author : Sergey ANIKIN, OCC +// Module : SMESH +// $Header$ + +#include "SMESH_Group_i.hxx" +#include "SMESH_Mesh_i.hxx" +#include "SMESH_Gen_i.hxx" +#include +#include +#include +#include + +//============================================================================= +/*! + * + */ +//============================================================================= + +SMESH_Group_i::SMESH_Group_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i* theMeshServant, const int theLocalID ) +: SALOME::GenericObj_i( thePOA ), + myMeshServant( theMeshServant ), + myLocalID( theLocalID ) +{ + thePOA->activate_object( this ); +} + + +//============================================================================= +/*! + * + */ +//============================================================================= + +SMESH_Group_i::~SMESH_Group_i() +{ + MESSAGE("~SMESH_Group_i;" ); + if ( myMeshServant ) + myMeshServant->removeGroup(myLocalID); +} + + +//============================================================================= +/*! + * + */ +//============================================================================= + +void SMESH_Group_i::SetName( const char* theName ) +{ + if ( myMeshServant ) { + ::SMESH_Mesh& aMesh = myMeshServant->GetImpl(); + ::SMESH_Group* aGroup = aMesh.GetGroup(myLocalID); + if (aGroup) { + aGroup->SetName(theName); + + // Update group name in a study + SALOMEDS::Study_var aStudy = myMeshServant->GetGen()->GetCurrentStudy(); + if ( !aStudy->_is_nil() ) { + SALOMEDS::SObject_var aGroupSO = aStudy->FindObjectIOR( SMESH_Gen_i::GetORB()->object_to_string( _this() ) ); + if ( !aGroupSO->_is_nil() ) { + SALOMEDS::StudyBuilder_var aBuilder = aStudy->NewBuilder(); + aBuilder->SetName( aGroupSO, theName ); + } + } + return; + } + } + MESSAGE("can't set name of a vague group"); +} + + +//============================================================================= +/*! + * + */ +//============================================================================= + +char* SMESH_Group_i::GetName() +{ + if ( myMeshServant ) { + ::SMESH_Mesh& aMesh = myMeshServant->GetImpl(); + ::SMESH_Group* aGroup = aMesh.GetGroup(myLocalID); + if (aGroup) + return CORBA::string_dup (aGroup->GetName()); + } + MESSAGE("get name of a vague group"); + return CORBA::string_dup( "NO_NAME" ); +} + + +//============================================================================= +/*! + * + */ +//============================================================================= + +SMESH::ElementType SMESH_Group_i::GetType() +{ + if ( myMeshServant ) { + ::SMESH_Mesh& aMesh = myMeshServant->GetImpl(); + ::SMESH_Group* aGroup = aMesh.GetGroup(myLocalID); + if (aGroup) { + SMDSAbs_ElementType aSMDSType = aGroup->GetGroupDS()->GetType(); + SMESH::ElementType aType; + switch (aSMDSType) { + case SMDSAbs_Node: aType = SMESH::NODE; break; + case SMDSAbs_Edge: aType = SMESH::EDGE; break; + case SMDSAbs_Face: aType = SMESH::FACE; break; + case SMDSAbs_Volume: aType = SMESH::VOLUME; break; + default: aType = SMESH::ALL; break; + } + return aType; + } + } + MESSAGE("get type of a vague group"); + return SMESH::ALL; +} + + +//============================================================================= +/*! + * + */ +//============================================================================= + +CORBA::Long SMESH_Group_i::Size() +{ + if ( myMeshServant ) { + ::SMESH_Mesh& aMesh = myMeshServant->GetImpl(); + ::SMESH_Group* aGroup = aMesh.GetGroup(myLocalID); + if (aGroup) { + int aSize = aGroup->GetGroupDS()->Extent(); + return aSize; + } + } + MESSAGE("get size of a vague group"); + return 0; +} + + +//============================================================================= +/*! + * + */ +//============================================================================= + +CORBA::Boolean SMESH_Group_i::IsEmpty() +{ + if ( myMeshServant ) { + ::SMESH_Mesh& aMesh = myMeshServant->GetImpl(); + ::SMESH_Group* aGroup = aMesh.GetGroup(myLocalID); + if (aGroup) { + bool isEmpty = aGroup->GetGroupDS()->IsEmpty(); + return isEmpty; + } + } + MESSAGE("checking IsEmpty of a vague group"); + return true; +} + + +//============================================================================= +/*! + * + */ +//============================================================================= + +void SMESH_Group_i::Clear() +{ + if ( myMeshServant ) { + ::SMESH_Mesh& aMesh = myMeshServant->GetImpl(); + ::SMESH_Group* aGroup = aMesh.GetGroup(myLocalID); + if (aGroup) { + // a SMDS group forgets its type after clearing, so we must re-set it + SMDSAbs_ElementType aSMDSType = aGroup->GetGroupDS()->GetType(); + aGroup->GetGroupDS()->Clear(); + aGroup->GetGroupDS()->SetType(aSMDSType); + return; + } + } + MESSAGE("attempt to clear a vague group"); +} + + +//============================================================================= +/*! + * + */ +//============================================================================= + +CORBA::Boolean SMESH_Group_i::Contains( CORBA::Long theID ) +{ + if ( myMeshServant ) { + ::SMESH_Mesh& aMesh = myMeshServant->GetImpl(); + ::SMESH_Group* aGroup = aMesh.GetGroup(myLocalID); + if (aGroup) { + bool res = aGroup->GetGroupDS()->Contains(theID); + return res; + } + } + MESSAGE("attempt to check contents of a vague group"); + return false; +} + + +//============================================================================= +/*! + * + */ +//============================================================================= + +CORBA::Long SMESH_Group_i::Add( const SMESH::long_array& theIDs ) +{ + if ( myMeshServant ) { + ::SMESH_Mesh& aMesh = myMeshServant->GetImpl(); + ::SMESH_Group* aGroup = aMesh.GetGroup(myLocalID); + if (aGroup) { + SMESHDS_Group* aGroupDS = aGroup->GetGroupDS(); + int nbAdd = 0; + for (int i = 0; i < theIDs.length(); i++) { + int anID = (int) theIDs[i]; + if (aGroupDS->Add(anID)) + nbAdd++; + } + return nbAdd; + } + } + MESSAGE("attempt to add elements to a vague group"); + return 0; +} + + +//============================================================================= +/*! + * + */ +//============================================================================= + +CORBA::Long SMESH_Group_i::GetID( CORBA::Long theIndex ) +{ + if ( myMeshServant ) { + ::SMESH_Mesh& aMesh = myMeshServant->GetImpl(); + ::SMESH_Group* aGroup = aMesh.GetGroup(myLocalID); + if (aGroup) { + int anID = aGroup->GetGroupDS()->GetID(theIndex); + return anID; + } + } + MESSAGE("attempt to iterate on a vague group"); + return -1; +} + + +//============================================================================= +/*! + * + */ +//============================================================================= + +SMESH::long_array* SMESH_Group_i::GetListOfID() +{ + SMESH::long_array_var aRes = new SMESH::long_array(); + if ( myMeshServant ) { + ::SMESH_Mesh& aMesh = myMeshServant->GetImpl(); + ::SMESH_Group* aGroup = aMesh.GetGroup(myLocalID); + if (aGroup) { + SMESHDS_Group* aGroupDS = aGroup->GetGroupDS(); + int aSize = aGroupDS->Extent(); + aRes->length(aSize); + for (int i = 0; i < aSize; i++) + aRes[i] = aGroupDS->GetID(i+1); + return aRes._retn(); + } + } + MESSAGE("get list of IDs of a vague group"); + return aRes._retn(); +} + + +//============================================================================= +/*! + * + */ +//============================================================================= + +CORBA::Long SMESH_Group_i::Remove( const SMESH::long_array& theIDs ) +{ + if ( myMeshServant ) { + ::SMESH_Mesh& aMesh = myMeshServant->GetImpl(); + ::SMESH_Group* aGroup = aMesh.GetGroup(myLocalID); + if (aGroup) { + // a SMDS group forgets its type after clearing, so we must re-set it + // if the group becomes empty + SMDSAbs_ElementType aSMDSType = aGroup->GetGroupDS()->GetType(); + SMESHDS_Group* aGroupDS = aGroup->GetGroupDS(); + int nbDel = 0; + for (int i = 0; i < theIDs.length(); i++) { + int anID = (int) theIDs[i]; + if (aGroupDS->Remove(anID)) + nbDel++; + } + if (aGroupDS->IsEmpty()) + aGroupDS->SetType(aSMDSType); + return nbDel; + } + } + MESSAGE("attempt to remove elements from a vague group"); + return 0; +} + + +//============================================================================= +/*! + * + */ +//============================================================================= +SMESH::SMESH_Mesh_ptr SMESH_Group_i::GetMesh() +{ + MESSAGE("SMESH_Group_i::GetMesh(): mesh servant = " << myMeshServant ); + SMESH::SMESH_Mesh_var aMesh; + if ( myMeshServant ) + aMesh = SMESH::SMESH_Mesh::_narrow( myMeshServant->_this() ); + return aMesh._retn(); +} + + +//============================================================================= +/*! + * + */ +//============================================================================= +int SMESH_Group_i::GetLocalID() +{ + return myLocalID; +} diff --git a/src/SMESH_I/SMESH_Group_i.hxx b/src/SMESH_I/SMESH_Group_i.hxx new file mode 100644 index 000000000..2c7c1d36f --- /dev/null +++ b/src/SMESH_I/SMESH_Group_i.hxx @@ -0,0 +1,82 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes +// +// Copyright (C) 2004 CEA +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH_Group_i.hxx +// Author : Sergey ANIKIN, OCC +// Module : SMESH +// $Header$ + +#ifndef SMESH_Group_i_HeaderFile +#define SMESH_Group_i_HeaderFile + +#include +#include CORBA_SERVER_HEADER(SMESH_Group) +#include CORBA_SERVER_HEADER(SMESH_Mesh) + +#include "SALOME_GenericObj_i.hh" + +class SMESH_Mesh_i; + +class SMESH_Group_i: + public virtual POA_SMESH::SMESH_Group, + public virtual SALOME::GenericObj_i +{ +public: + SMESH_Group_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i* theMeshServant, const int theLocalID ); + virtual ~SMESH_Group_i(); + + // CORBA interface implementation + void SetName( const char* theName ); + + char* GetName(); + + SMESH::ElementType GetType(); + + CORBA::Long Size(); + + CORBA::Boolean IsEmpty(); + + void Clear(); + + CORBA::Boolean Contains( CORBA::Long theID ); + + CORBA::Long Add( const SMESH::long_array& theIDs ); + + CORBA::Long GetID( CORBA::Long theIndex ); + + SMESH::long_array* GetListOfID(); + + CORBA::Long Remove( const SMESH::long_array& theIDs ); + + SMESH::SMESH_Mesh_ptr GetMesh(); + + // Internal C++ interface + int GetLocalID(); + + SMESH_Mesh_i* GetMeshServant() { return myMeshServant; } + +private: + SMESH_Mesh_i* myMeshServant; + int myLocalID; +}; + +#endif diff --git a/src/SMESH_I/SMESH_HypothesisFactory_i.cxx b/src/SMESH_I/SMESH_HypothesisFactory_i.cxx deleted file mode 100644 index efb8134d5..000000000 --- a/src/SMESH_I/SMESH_HypothesisFactory_i.cxx +++ /dev/null @@ -1,142 +0,0 @@ -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses -// -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org -// -// -// -// File : SMESH_HypothesisFactory_i.cxx -// Author : Paul RASCLE, EDF -// Module : SMESH -// $Header$ - -using namespace std; -#include "SMESH_HypothesisFactory_i.hxx" -#include "SMESH_Hypothesis_i.hxx" - -#include "Utils_CorbaException.hxx" -#include "utilities.h" - -// Add new hypothesis here (include file) -//--------------------------------------- -#include "SMESH_LocalLength_i.hxx" -#include "SMESH_NumberOfSegments_i.hxx" -#include "SMESH_LengthFromEdges_i.hxx" -#include "SMESH_MaxElementArea_i.hxx" -#include "SMESH_MaxElementVolume_i.hxx" -#include "SMESH_Regular_1D_i.hxx" -#include "SMESH_MEFISTO_2D_i.hxx" -#include "SMESH_Quadrangle_2D_i.hxx" -#include "SMESH_Hexa_3D_i.hxx" -#ifdef HAVE_NETGEN -#include "SMESH_NETGEN_3D_i.hxx" -#endif -//--------------------------------------- - -//============================================================================= -/*! - * Specific Hypothesis Creators are generated with a template which inherits a - * generic hypothesis creator. Each creator returns an hypothesis of the type - * given in the template. - */ -//============================================================================= - -template class HypothesisCreator_i: public GenericHypothesisCreator_i -{ -public: - virtual SMESH_Hypothesis_i* Create (const char* anHyp, - int studyId, - ::SMESH_Gen* genImpl) - { - return new T(anHyp, studyId, genImpl); - }; -}; - -//============================================================================= -/*! - * Constructor: instanciate specific hypothesis creators, fill a private map - * indexed by hypothesis names. THIS METHOD MUST BE COMPLETED WHEN A NEW - * HYPOTHESIS IS ADDED. - * Specific hypothesis creator are defined with the above template. - * Hypothesis names are related to the corresponding class names: - * prefix = SMESH_ ; suffix = _i . - */ -//============================================================================= - -SMESH_HypothesisFactory_i::SMESH_HypothesisFactory_i() -{ -// Add new hypothesis here (creators) -//--------------------------------------- -_creatorMap["LocalLength"] = new HypothesisCreator_i; -_creatorMap["NumberOfSegments"] = new HypothesisCreator_i; -_creatorMap["LengthFromEdges"] = new HypothesisCreator_i; -_creatorMap["MaxElementArea"] = new HypothesisCreator_i; -_creatorMap["MaxElementVolume"] = new HypothesisCreator_i; -_creatorMap["Regular_1D"] = new HypothesisCreator_i; -_creatorMap["MEFISTO_2D"] = new HypothesisCreator_i; -_creatorMap["Quadrangle_2D"] = new HypothesisCreator_i; -_creatorMap["Hexa_3D"] = new HypothesisCreator_i; -#ifdef HAVE_NETGEN -_creatorMap["NETGEN_3D"] = new HypothesisCreator_i; -#endif -//--------------------------------------- -} - -//============================================================================= -/*! - * Destructor: deletes specific hypothesis creators instanciated in the - * constructor. - */ -//============================================================================= - -SMESH_HypothesisFactory_i::~SMESH_HypothesisFactory_i() -{ - map::iterator it; - for (it = _creatorMap.begin(); it != _creatorMap.end(); it++) - { - delete (*it).second; - } - _creatorMap.clear(); -} - -//============================================================================= -/*! - * - */ -//============================================================================= - -SMESH_Hypothesis_i* SMESH_HypothesisFactory_i::Create(const char* anHyp, - CORBA::Long studyId, - ::SMESH_Gen* genImpl) - throw (SALOME::SALOME_Exception) -{ - MESSAGE("SMESH_HypothesisFactory::Create " << anHyp); - if (_creatorMap.find(anHyp) == _creatorMap.end()) - { - MESSAGE("levee exception CORBA"); - THROW_SALOME_CORBA_EXCEPTION("bad hypothesis type name", \ - SALOME::BAD_PARAM); - } - SMESH_Hypothesis_i* myHyp = _creatorMap[anHyp]->Create(anHyp, - studyId, - genImpl); - return myHyp; -} - - diff --git a/src/SMESH_I/SMESH_Hypothesis_i.cxx b/src/SMESH_I/SMESH_Hypothesis_i.cxx index 96ddd7e3a..87c16ee4e 100644 --- a/src/SMESH_I/SMESH_Hypothesis_i.cxx +++ b/src/SMESH_I/SMESH_Hypothesis_i.cxx @@ -27,62 +27,139 @@ // $Header$ using namespace std; -using namespace std; +#include +#include #include "SMESH_Hypothesis_i.hxx" -#include "SMESH_Hypothesis.hxx" -#include "SMESH_Gen.hxx" #include "utilities.h" //============================================================================= /*! - * + * SMESH_Hypothesis_i::SMESH_Hypothesis_i + * + * Constructor */ //============================================================================= -SMESH_Hypothesis_i::SMESH_Hypothesis_i() +SMESH_Hypothesis_i::SMESH_Hypothesis_i( PortableServer::POA_ptr thePOA ) + : SALOME::GenericObj_i( thePOA ) { - MESSAGE("SMESH_Hypothesis_i"); + MESSAGE( "SMESH_Hypothesis_i::SMESH_Hypothesis_i" ); + myBaseImpl = 0; + thePOA->activate_object( this ); }; //============================================================================= /*! - * + * SMESH_Hypothesis_i::~SMESH_Hypothesis_i + * + * Destructor */ //============================================================================= SMESH_Hypothesis_i::~SMESH_Hypothesis_i() { - MESSAGE("~SMESH_Hypothesis_i"); + MESSAGE( "SMESH_Hypothesis_i::~SMESH_Hypothesis_i" ); + if ( myBaseImpl ) + delete myBaseImpl; }; //============================================================================= /*! - * + * SMESH_Hypothesis_i::GetName + * + * Get type name of hypothesis */ //============================================================================= char* SMESH_Hypothesis_i::GetName() { - MESSAGE("GetName"); - return CORBA::string_dup(_baseImpl->GetName()); -// const char* name = _baseImpl->GetName(); -// SCRUTE(name); -// return CORBA::string_dup(name); + MESSAGE( "SMESH_Hypothesis_i::GetName" ); + return CORBA::string_dup( myBaseImpl->GetName() ); +}; + +//============================================================================= +/*! + * SMESH_Hypothesis_i::GetLibName + * + * Get plugin library name of hypothesis (required by persistency mechanism) + */ +//============================================================================= + +char* SMESH_Hypothesis_i::GetLibName() +{ + MESSAGE( "SMESH_Hypothesis_i::GetLibName" ); + return CORBA::string_dup( myBaseImpl->GetLibName() ); }; //============================================================================= /*! - * + * SMESH_Hypothesis_i::SetLibName + * + * Set plugin library name of hypothesis (required by persistency mechanism) + */ +//============================================================================= + +void SMESH_Hypothesis_i::SetLibName(const char* theLibName) +{ + MESSAGE( "SMESH_Hypothesis_i::SetLibName" ); + myBaseImpl->SetLibName( theLibName ); +}; + +//============================================================================= +/*! + * SMESH_Hypothesis_i::GetId + * + * Get unique id of hypothesis */ //============================================================================= CORBA::Long SMESH_Hypothesis_i::GetId() { - MESSAGE("GetId"); - return _baseImpl->GetID(); + MESSAGE( "SMESH_Hypothesis_i::GetId" ); + return myBaseImpl->GetID(); +} + +//============================================================================= +/*! + * SMESH_Hypothesis_i::GetImpl + * + * Get implementation + */ +//============================================================================= + +::SMESH_Hypothesis* SMESH_Hypothesis_i::GetImpl() +{ + MESSAGE( "SMESH_Hypothesis_i::GetImpl" ); + return myBaseImpl; } -::SMESH_Hypothesis* SMESH_Hypothesis_i::getImpl() +//============================================================================= +/*! + * SMESH_Hypothesis_i::SaveTo + * + * Persistence: Dumps parameters to the string stream + */ +//============================================================================= + +char* SMESH_Hypothesis_i::SaveTo() { - return _baseImpl; -} \ No newline at end of file + MESSAGE( "SMESH_Hypothesis_i::SaveTo" ); + std::ostringstream os; + myBaseImpl->SaveTo( os ); + return CORBA::string_dup( os.str().c_str() ); +} + +//============================================================================= +/*! +* SMESH_Hypothesis_i::LoadFrom +* +* Persistence: Restores parameters from string +*/ +//============================================================================= + +void SMESH_Hypothesis_i::LoadFrom( const char* theStream ) +{ + MESSAGE( "SMESH_Hypothesis_i::LoadFrom" ); + std::istringstream is( theStream ); + myBaseImpl->LoadFrom( is ); +} diff --git a/src/SMESH_I/SMESH_Hypothesis_i.hxx b/src/SMESH_I/SMESH_Hypothesis_i.hxx index 686e6877b..5a03bfa44 100644 --- a/src/SMESH_I/SMESH_Hypothesis_i.hxx +++ b/src/SMESH_I/SMESH_Hypothesis_i.hxx @@ -32,24 +32,77 @@ #include #include CORBA_SERVER_HEADER(SMESH_Hypothesis) -class SMESH_Gen; -class SMESH_Hypothesis; +#include "SMESH_Hypothesis.hxx" +#include "SALOME_GenericObj_i.hh" +#include "SMESH_Gen.hxx" + +// ====================================================== +// Generic hypothesis +// ====================================================== class SMESH_Hypothesis_i: - public POA_SMESH::SMESH_Hypothesis + public virtual POA_SMESH::SMESH_Hypothesis, + public virtual SALOME::GenericObj_i { public: - SMESH_Hypothesis_i(); + // Constructor : placed in protected section to prohibit creation of generic class instance + SMESH_Hypothesis_i( PortableServer::POA_ptr thePOA ); + +public: + // Destructor virtual ~SMESH_Hypothesis_i(); + // Get type name of hypothesis char* GetName(); + + // Get plugin library name of hypothesis + char* GetLibName(); + + // Set plugin library name of hypothesis + void SetLibName( const char* theLibName ); + + // Get unique id of hypothesis CORBA::Long GetId(); - ::SMESH_Hypothesis* getImpl(); + + // Get implementation + ::SMESH_Hypothesis* GetImpl(); + + // Persistence + virtual char* SaveTo(); + virtual void LoadFrom( const char* theStream ); protected: - ::SMESH_Hypothesis* _baseImpl; - ::SMESH_Gen* _genImpl; - int _id; + ::SMESH_Hypothesis* myBaseImpl; // base hypothesis implementation +}; + +// ====================================================== +// Generic hypothesis creator +// ====================================================== +class GenericHypothesisCreator_i +{ +public: + // Create a hypothesis + virtual SMESH_Hypothesis_i* Create(PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl) = 0; +}; + +//============================================================================= +// +// Specific Hypothesis Creators are generated with a template which inherits a +// generic hypothesis creator. Each creator returns an hypothesis of the type +// given in the template. +// +//============================================================================= +template class HypothesisCreator_i: public GenericHypothesisCreator_i +{ +public: + virtual SMESH_Hypothesis_i* Create (PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl) + { + return new T (thePOA, theStudyId, theGenImpl); + }; }; #endif diff --git a/src/SMESH_I/SMESH_MEDMesh_i.cxx b/src/SMESH_I/SMESH_MEDMesh_i.cxx index 25ce55bfe..82917f4ad 100644 --- a/src/SMESH_I/SMESH_MEDMesh_i.cxx +++ b/src/SMESH_I/SMESH_MEDMesh_i.cxx @@ -54,6 +54,8 @@ using namespace std; # include "Utils_ORB_INIT.hxx" # include "Utils_SINGLETON.hxx" +# include "Utils_ExceptHandlers.hxx" + extern "C" { #include @@ -254,7 +256,7 @@ SALOME_MED::double_array * SMESH_MEDMesh_i::getCoordinates( myseq->length(nbNodes * spaceDimension); int i = 0; - SMDS_Iterator * itNodes=_meshDS->nodesIterator(); + SMDS_NodeIteratorPtr itNodes=_meshDS->nodesIterator(); while(itNodes->more()) { const SMDS_MeshNode* node = itNodes->next(); @@ -280,7 +282,6 @@ SALOME_MED::double_array * SMESH_MEDMesh_i::getCoordinates( } i++; } - delete itNodes; } catch(...) { @@ -949,7 +950,7 @@ void SMESH_MEDMesh_i::calculeNbElts() throw(SALOME::SALOME_Exception) int trouveSeg3 = 0; SALOME_MED::medGeometryElement medElement; - SMDS_Iterator * itEdges=_meshDS->edgesIterator(); + SMDS_EdgeIteratorPtr itEdges=_meshDS->edgesIterator(); while(itEdges->more()) { const SMDS_MeshEdge* elem = itEdges->next(); @@ -987,13 +988,11 @@ void SMESH_MEDMesh_i::calculeNbElts() throw(SALOME::SALOME_Exception) int longueur = _seq_elemId[index]->length(); _seq_elemId[index]->length(longueur + nb_of_nodes); - SMDS_Iterator * itn=_meshDS->nodesIterator(); + SMDS_NodeIteratorPtr itn=_meshDS->nodesIterator(); for(int k=0; itn->more(); k++) _seq_elemId[index][longueur + k] = itn->next()->GetID()+1; - delete itn; } - delete itEdges; _mapNbTypes[SALOME_MED::MED_EDGE] = trouveSeg2 + trouveSeg3; @@ -1008,7 +1007,7 @@ void SMESH_MEDMesh_i::calculeNbElts() throw(SALOME::SALOME_Exception) _mapIndToSeqElts[SALOME_MED::MED_QUAD4] = _indexElts++; _mapIndToVectTypes[SALOME_MED::MED_FACE] = _indexEnts++; - SMDS_Iterator * itFaces=_meshDS->facesIterator(); + SMDS_FaceIteratorPtr itFaces=_meshDS->facesIterator(); while(itFaces->more()) { const SMDS_MeshFace * elem = itFaces->next(); @@ -1059,13 +1058,11 @@ void SMESH_MEDMesh_i::calculeNbElts() throw(SALOME::SALOME_Exception) int longueur = _seq_elemId[index]->length(); _seq_elemId[index]->length(longueur + nb_of_nodes); - SMDS_Iterator * itn=_meshDS->nodesIterator(); + SMDS_NodeIteratorPtr itn=_meshDS->nodesIterator(); for(int k=0; itn->more(); k++) _seq_elemId[index][longueur + k] = itn->next()->GetID()+1; - delete itn; } //itFaces - delete itFaces; _mapNbTypes[SALOME_MED::MED_FACE] = trouveTria3 + trouveTria6 + trouveQuad4; @@ -1076,7 +1073,7 @@ void SMESH_MEDMesh_i::calculeNbElts() throw(SALOME::SALOME_Exception) int trouveHexa8 = 0; - SMDS_Iterator * itVolumes=_meshDS->volumesIterator(); + SMDS_VolumeIteratorPtr itVolumes=_meshDS->volumesIterator(); while(itVolumes->more()) { const SMDS_MeshVolume * elem = itVolumes->next(); @@ -1094,12 +1091,10 @@ void SMESH_MEDMesh_i::calculeNbElts() throw(SALOME::SALOME_Exception) int longueur = _seq_elemId[index]->length(); _seq_elemId[index]->length(longueur + nb_of_nodes); - SMDS_Iterator * itn=_meshDS->nodesIterator(); + SMDS_NodeIteratorPtr itn=_meshDS->nodesIterator(); for(int k=0; itn->more(); k++) _seq_elemId[index][longueur + k] = itn->next()->GetID()+1; - delete itn; } - delete itVolumes; _mapNbTypes[SALOME_MED::MED_CELL] = trouveHexa8; _mapNbTypes[SALOME_MED::MED_ALL_ENTITIES] @@ -1116,6 +1111,7 @@ void SMESH_MEDMesh_i::calculeNbElts() throw(SALOME::SALOME_Exception) //============================================================================= void SMESH_MEDMesh_i::createFamilies() throw(SALOME::SALOME_Exception) { + Unexpect aCatch(SALOME_SalomeException); string famDes = ("Je ne sais pas"); string famName0 = "Famille_"; string famName; diff --git a/src/SMESH_I/SMESH_MEDSupport_i.cxx b/src/SMESH_I/SMESH_MEDSupport_i.cxx index ba72f1973..7b5289ebb 100644 --- a/src/SMESH_I/SMESH_MEDSupport_i.cxx +++ b/src/SMESH_I/SMESH_MEDSupport_i.cxx @@ -28,6 +28,7 @@ using namespace std; #include "SMESH_MEDSupport_i.hxx" #include "utilities.h" #include "Utils_CorbaException.hxx" +#include "Utils_ExceptHandlers.hxx" #include #include "SMESHDS_Mesh.hxx" @@ -36,6 +37,7 @@ using namespace std; #include "SMESH_Mesh_i.hxx" #include "SMESH_subMesh_i.hxx" + //============================================================================= /*! * Default constructor @@ -296,6 +298,7 @@ CORBA::Long SMESH_MEDSupport_i::getNumberOfElements(SALOME_MED:: SALOME_MED::long_array * SMESH_MEDSupport_i::getNumber( SALOME_MED::medGeometryElement geomElement) throw(SALOME::SALOME_Exception) { + Unexpect aCatch(SALOME_SalomeException); if (_subMeshDS==NULL) THROW_SALOME_CORBA_EXCEPTION("No associated Support", SALOME::INTERNAL_ERROR); @@ -309,13 +312,12 @@ SALOME_MED::long_array * SMESH_MEDSupport_i::getNumber( int i = 0; myseq->length(_subMeshDS->NbNodes()); - SMDS_Iterator * it = _subMeshDS->GetNodes(); + SMDS_NodeIteratorPtr it = _subMeshDS->GetNodes(); while(it->more()) { myseq[i] = it->next()->GetID(); i++; }; - delete it; SCRUTE(myseq->length()); MESSAGE("End of SMESH_MEDSupport_i::getNumber"); diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index 89088d3f6..99b27b0bb 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -61,8 +61,14 @@ CORBA::Boolean SMESH_MeshEditor_i::RemoveElements(const SMESH:: for (int i = 0; i < IDsOfElements.length(); i++) { CORBA::Long index = IDsOfElements[i]; - _myMeshDS->RemoveElement(_myMeshDS->FindElement(index)); - MESSAGE("Element " << index << " was removed") + const SMDS_MeshElement * elem = _myMeshDS->FindElement(index); + // an element may be removed as a result of preceding + // loop removal + if ( elem ) + { + _myMeshDS->RemoveElement( elem ); + MESSAGE("Element " << index << " was removed"); + } } return true; }; diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index 2c051c72b..9b3352a64 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -26,11 +26,14 @@ // Module : SMESH // $Header$ +using namespace std; #include "SMESH_Mesh_i.hxx" #include "SMESH_subMesh_i.hxx" #include "SMESH_MEDMesh_i.hxx" +#include "SMESH_Group_i.hxx" #include "Utils_CorbaException.hxx" +#include "Utils_ExceptHandlers.hxx" #include "utilities.h" #include "SALOME_NamingService.hxx" @@ -41,27 +44,58 @@ #include "SMESHDS_Command.hxx" #include "SMESHDS_CommandType.hxx" #include "SMESH_MeshEditor_i.hxx" +#include "SMESH_Gen_i.hxx" +#include "DriverMED_R_SMESHDS_Mesh.h" #include #include -using namespace std; + + +//**** SMESHDS en champ + +int SMESH_Mesh_i::myIdGenerator = 0; //============================================================================= /*! - * Constructor + * */ //============================================================================= -SMESH_Mesh_i::SMESH_Mesh_i(SMESH_Gen_i * gen_i, - GEOM::GEOM_Gen_ptr geomEngine, CORBA::Long studyId, ::SMESH_Mesh * impl) +SMESH_Mesh_i::SMESH_Mesh_i() + : SALOME::GenericObj_i( PortableServer::POA::_nil() ) { - MESSAGE("SMESH_Mesh_i"); - _gen_i = gen_i; - _geom = GEOM::GEOM_Gen::_narrow(geomEngine); - _impl=impl; - _studyId=studyId; + MESSAGE("SMESH_Mesh_i: default constructor, not for use"); + ASSERT(0); } +//============================================================================= +/*! + * Constructor + */ +//============================================================================= + +SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA, + SMESH_Gen_i* gen_i, + CORBA::Long studyId ) +: SALOME::GenericObj_i( thePOA ) +{ + MESSAGE("SMESH_Mesh_i"); + _gen_i = gen_i; + _id = myIdGenerator++; + _studyId = studyId; + thePOA->activate_object( this ); +} +/* +SMESH_Mesh_i::SMESH_Mesh_i(SMESH_Gen_i* gen_i, + CORBA::Long studyId, + int localId) +{ + MESSAGE("SMESH_Mesh_i"); + _gen_i = gen_i; + _id = localId; + _studyId = studyId; +} +*/ //============================================================================= /*! * Destructor @@ -70,9 +104,81 @@ SMESH_Mesh_i::SMESH_Mesh_i(SMESH_Gen_i * gen_i, SMESH_Mesh_i::~SMESH_Mesh_i() { - MESSAGE("~SMESH_Mesh_i"); - // **** -}; + MESSAGE("~SMESH_Mesh_i"); + map::iterator it; + for ( it = _mapGroups.begin(); it != _mapGroups.end(); it++ ) { + SMESH_Group_i* aGroup = dynamic_cast( SMESH_Gen_i::GetServant( it->second ).in() ); + if ( aGroup ) { + _impl->RemoveGroup( aGroup->GetLocalID() ); + aGroup->Destroy(); + } + } + _mapGroups.clear(); +} + +//============================================================================= +/*! + * SetShape + * + * Associates mesh with and puts a reference + * to into the current study; + * the previous shape is substituted by the new one. + */ +//============================================================================= + +void SMESH_Mesh_i::SetShape( GEOM::GEOM_Shape_ptr theShape ) + throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + try { + setShape( theShape ); + } + catch(SALOME_Exception & S_ex) { + THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); + } + + SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); + if ( aStudy->_is_nil() ) + return; + + // Create a reference to + SALOMEDS::SObject_var aMeshSO = SALOMEDS::SObject::_narrow( aStudy->FindObjectIOR( ( SMESH_Gen_i::GetORB()->object_to_string( _this() ) ) ) ); + SALOMEDS::SObject_var aShapeSO = aStudy->FindObjectIOR( SMESH_Gen_i::GetORB()->object_to_string( theShape ) ); + + SALOMEDS::SObject_var anObj, aRef; + SALOMEDS::GenericAttribute_var anAttr; + SALOMEDS::AttributeIOR_var anIOR; + SALOMEDS::StudyBuilder_var aBuilder = aStudy->NewBuilder(); + long aTag = SMESH_Gen_i::GetRefOnShapeTag(); + + if ( aMeshSO->FindSubObject( aTag, anObj ) ) { + if ( anObj->ReferencedObject( aRef ) ) { + if ( strcmp( aRef->GetID(), aShapeSO->GetID() ) == 0 ) { + // Setting the same shape twice forbidden + return; + } + } + } + else { + anObj = aBuilder->NewObjectToTag( aMeshSO, aTag ); + } + aBuilder->Addreference( anObj, aShapeSO ); +} + +//============================================================================= +/*! + * setShape + * + * Sets shape to the mesh implementation + */ +//============================================================================= + +bool SMESH_Mesh_i::setShape( GEOM::GEOM_Shape_ptr theShape ) +{ + TopoDS_Shape aLocShape = _gen_i->GetShapeReader()->GetShape( SMESH_Gen_i::GetGeomEngine(), theShape ); + _impl->ShapeToMesh( aLocShape ); + return true; +} //============================================================================= /*! @@ -80,10 +186,217 @@ SMESH_Mesh_i::~SMESH_Mesh_i() */ //============================================================================= -CORBA::Boolean SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Shape_ptr aSubShape, - SMESH::SMESH_Hypothesis_ptr anHyp) throw(SALOME::SALOME_Exception) +static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus) { - MESSAGE("AddHypothesis"); + SMESH::DriverMED_ReadStatus res; + switch (theStatus) + { + case DriverMED_R_SMESHDS_Mesh::DRS_OK: + res = SMESH::DRS_OK; break; + case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY: + res = SMESH::DRS_EMPTY; break; + case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER: + res = SMESH::DRS_WARN_RENUMBER; break; + case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM: + res = SMESH::DRS_WARN_SKIP_ELEM; break; + case DriverMED_R_SMESHDS_Mesh::DRS_FAIL: + default: + res = SMESH::DRS_FAIL; break; + } + return res; +} + +//============================================================================= +/*! + * ImportMEDFile + * + * Imports mesh data from MED file + */ +//============================================================================= + +SMESH::DriverMED_ReadStatus + SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName ) + throw ( SALOME::SALOME_Exception ) +{ + Unexpect aCatch(SALOME_SalomeException); + int status; + try { + status = importMEDFile( theFileName, theMeshName ); + } + catch( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); + } + catch ( ... ) { + THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM); + } + + SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); + if ( aStudy->_is_nil() ) + return ConvertDriverMEDReadStatus(status); + + // publishing of the groups in the study (sub-meshes are out of scope of MED import) + map::iterator it = _mapGroups.begin(); + for (; it != _mapGroups.end(); it++ ) { + SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_duplicate( it->second ); + if ( _gen_i->CanPublishInStudy( aGroup ) ) + _gen_i->PublishInStudy( aStudy, + SALOMEDS::SObject::_nil(), + aGroup, + aGroup->GetName() ); + } + return ConvertDriverMEDReadStatus(status); +} + +//============================================================================= +/*! + * importMEDFile + * + * Imports mesh data from MED file + */ +//============================================================================= + +int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshName ) +{ + // Read mesh with name = and all its groups into SMESH_Mesh + int status = _impl->MEDToMesh( theFileName, theMeshName ); + + // Create group servants, if any groups were imported + list aGroupIds = _impl->GetGroupIds(); + for ( list::iterator it = aGroupIds.begin(); it != aGroupIds.end(); it++ ) { + SMESH_Group_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, *it ); + SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() ); + _mapGroups[*it] = SMESH::SMESH_Group::_duplicate( aGroup ); + + // register CORBA object for persistence + StudyContext* myStudyContext = _gen_i->GetCurrentStudyContext(); + string iorString = SMESH_Gen_i::GetORB()->object_to_string( aGroup ); + int nextId = myStudyContext->addObject( iorString ); + MESSAGE( "Add group to map with id = "<< nextId << " and IOR = " << iorString.c_str() ); + } + + return status; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +static SMESH::Hypothesis_Status ConvertHypothesisStatus + (SMESH_Hypothesis::Hypothesis_Status theStatus) +{ + SMESH::Hypothesis_Status res; + switch (theStatus) + { + case SMESH_Hypothesis::HYP_OK: + res = SMESH::HYP_OK; break; + case SMESH_Hypothesis::HYP_MISSING: + res = SMESH::HYP_MISSING; break; + case SMESH_Hypothesis::HYP_CONCURENT: + res = SMESH::HYP_CONCURENT; break; + case SMESH_Hypothesis::HYP_BAD_PARAMETER: + res = SMESH::HYP_BAD_PARAMETER; break; + case SMESH_Hypothesis::HYP_INCOMPATIBLE: + res = SMESH::HYP_INCOMPATIBLE; break; + case SMESH_Hypothesis::HYP_NOTCONFORM: + res = SMESH::HYP_NOTCONFORM; break; + case SMESH_Hypothesis::HYP_ALREADY_EXIST: + res = SMESH::HYP_ALREADY_EXIST; break; + case SMESH_Hypothesis::HYP_BAD_DIM: + res = SMESH::HYP_BAD_DIM; break; + default: + res = SMESH::HYP_UNKNOWN_FATAL; + } + return res; +} + +//============================================================================= +/*! + * AddHypothesis + * + * calls internal addHypothesis() and then adds a reference to under + * the SObject actually having a reference to . + * NB: For this method to work, it is necessary to add a reference to sub-shape first. + */ +//============================================================================= + +SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Shape_ptr aSubShape, + SMESH::SMESH_Hypothesis_ptr anHyp) + throw(SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp ); + + if ( !SMESH_Hypothesis::IsStatusFatal(status) ) { + SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); + + if ( !aStudy->_is_nil() ) { + // Detect whether refers to this mesh or its sub-mesh + SALOMEDS::GenericAttribute_var anAttr; + SALOMEDS::AttributeIOR_var anIOR; + SALOMEDS::SObject_var aMeshSO = SALOMEDS::SObject::_narrow( aStudy->FindObjectIOR( ( SMESH_Gen_i::GetORB()->object_to_string( _this() ) ) ) ); + SALOMEDS::SObject_var aMorSM, aRef; + CORBA::String_var aShapeIOR = CORBA::string_dup( SMESH_Gen_i::GetORB()->object_to_string( aSubShape ) ); + SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator( aMeshSO ); + + for ( it->InitEx( true ); it->More(); it->Next() ) { + SALOMEDS::SObject_var anObj = it->Value(); + if ( anObj->ReferencedObject( aRef ) ) { + if ( aRef->FindAttribute( anAttr, "AttributeIOR" ) ) { + anIOR = SALOMEDS::AttributeIOR::_narrow( anAttr ); + if ( strcmp( anIOR->Value(), aShapeIOR ) == 0 ) { + aMorSM = anObj->GetFather(); + break; + } + } + } + } + + bool aIsAlgo = !SMESH::SMESH_Algo::_narrow( anHyp )->_is_nil(); + SALOMEDS::SObject_var aHypSO = SALOMEDS::SObject::_narrow( aStudy->FindObjectIOR( ( SMESH_Gen_i::GetORB()->object_to_string( anHyp ) ) ) ); + if ( !aMorSM->_is_nil() && !aHypSO->_is_nil() ) { + //Find or Create Applied Hypothesis root + SALOMEDS::SObject_var AHR; + SALOMEDS::AttributeName_var aName; + SALOMEDS::AttributeSelectable_var aSelAttr; + SALOMEDS::AttributePixMap_var aPixmap; + SALOMEDS::StudyBuilder_var aBuilder = aStudy->NewBuilder(); + long aTag = aIsAlgo ? SMESH_Gen_i::GetRefOnAppliedAlgorithmsTag() : SMESH_Gen_i::GetRefOnAppliedHypothesisTag(); + + if ( !aMorSM->FindSubObject( aTag, AHR ) ) { + AHR = aBuilder->NewObjectToTag( aMorSM, aTag ); + anAttr = aBuilder->FindOrCreateAttribute( AHR, "AttributeName" ); + aName = SALOMEDS::AttributeName::_narrow( anAttr ); + aName ->SetValue( aIsAlgo ? "Applied algorithms" : "Applied hypotheses" ); + anAttr = aBuilder->FindOrCreateAttribute( AHR, "AttributeSelectable" ); + aSelAttr = SALOMEDS::AttributeSelectable::_narrow( anAttr ); + aSelAttr ->SetSelectable( false ); + anAttr = aBuilder->FindOrCreateAttribute( AHR, "AttributePixMap" ); + aPixmap = SALOMEDS::AttributePixMap::_narrow( anAttr ); + aPixmap ->SetPixMap( aIsAlgo ? "ICON_SMESH_TREE_ALGO" : "ICON_SMESH_TREE_HYPO" ); + } + + SALOMEDS::SObject_var SO = aBuilder->NewObject( AHR ); + aBuilder->Addreference( SO, aHypSO ); + } + } + } + + return ConvertHypothesisStatus(status); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +SMESH_Hypothesis::Hypothesis_Status + SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Shape_ptr aSubShape, + SMESH::SMESH_Hypothesis_ptr anHyp) +{ + MESSAGE("addHypothesis"); // **** proposer liste de subShape (selection multiple) GEOM::GEOM_Shape_var mySubShape = GEOM::GEOM_Shape::_narrow(aSubShape); @@ -95,20 +408,99 @@ CORBA::Boolean SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Shape_ptr aSubShape, if (CORBA::is_nil(myHyp)) THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM); - bool ret = false; + + SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK; try { TopoDS_Shape myLocSubShape = - _gen_i->_ShapeReader->GetShape(_geom, mySubShape); + _gen_i->GetShapeReader()->GetShape(SMESH_Gen_i::GetGeomEngine(), mySubShape); int hypId = myHyp->GetId(); - ret = _impl->AddHypothesis(myLocSubShape, hypId); + status = _impl->AddHypothesis(myLocSubShape, hypId); + if ( !SMESH_Hypothesis::IsStatusFatal(status) ) + _mapHypo[hypId] = myHyp; } catch(SALOME_Exception & S_ex) { THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); } - return ret; -}; + return status; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Shape_ptr aSubShape, + SMESH::SMESH_Hypothesis_ptr anHyp) + throw(SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp ); + + if ( !SMESH_Hypothesis::IsStatusFatal(status) ) { + SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); + + if ( !aStudy->_is_nil() ) { + // Detect whether refers to this mesh or its sub-mesh + SALOMEDS::GenericAttribute_var anAttr; + SALOMEDS::AttributeIOR_var anIOR; + SALOMEDS::SObject_var aMeshSO = SALOMEDS::SObject::_narrow( aStudy->FindObjectIOR( ( SMESH_Gen_i::GetORB()->object_to_string( _this() ) ) ) ); + if ( aMeshSO->_is_nil() ) + return SMESH::HYP_UNKNOWN_FATAL; + + SALOMEDS::SObject_var aMorSM, aRef; + CORBA::String_var aShapeIOR = CORBA::string_dup( SMESH_Gen_i::GetORB()->object_to_string( aSubShape ) ); + SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator( aMeshSO ); + + for ( it->InitEx( true ); it->More(); it->Next() ) { + SALOMEDS::SObject_var anObj = it->Value(); + if ( anObj->ReferencedObject( aRef ) ) { + if ( aRef->FindAttribute( anAttr, "AttributeIOR" ) ) { + anIOR = SALOMEDS::AttributeIOR::_narrow( anAttr ); + if ( strcmp( anIOR->Value(), aShapeIOR ) == 0 ) { + aMorSM = anObj->GetFather(); + break; + } + } + } + } + + bool aIsAlgo = !SMESH::SMESH_Algo::_narrow( anHyp )->_is_nil(); + SALOMEDS::SObject_var aHypSO = SALOMEDS::SObject::_narrow( aStudy->FindObjectIOR( ( SMESH_Gen_i::GetORB()->object_to_string( anHyp ) ) ) ); + if ( !aMorSM->_is_nil() && !aHypSO->_is_nil() ) { + // Remove a refernce to hypothesis or algorithm + SALOMEDS::SObject_var AHR; + SALOMEDS::AttributeName_var aName; + SALOMEDS::AttributeSelectable_var aSelAttr; + SALOMEDS::AttributePixMap_var aPixmap; + SALOMEDS::StudyBuilder_var aBuilder = aStudy->NewBuilder(); + CORBA::String_var aHypIOR = CORBA::string_dup( SMESH_Gen_i::GetORB()->object_to_string( anHyp ) ); + long aTag = aIsAlgo ? SMESH_Gen_i::GetRefOnAppliedAlgorithmsTag() : SMESH_Gen_i::GetRefOnAppliedHypothesisTag(); + + if ( aMorSM->FindSubObject( aTag, AHR ) ) { + SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator( AHR ); + for ( ; it->More(); it->Next() ) { + SALOMEDS::SObject_var anObj = it->Value(); + if ( anObj->ReferencedObject( aRef ) ) { + if ( aRef->FindAttribute( anAttr, "AttributeIOR" ) ) { + anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + if ( strcmp( anIOR->Value(), aHypIOR ) == 0 ) { + aBuilder->RemoveObject( anObj ); + break; + } + } + } + } + } + } + } + } + + return ConvertHypothesisStatus(status); +} + //============================================================================= /*! @@ -116,11 +508,11 @@ CORBA::Boolean SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Shape_ptr aSubShape, */ //============================================================================= -CORBA::Boolean - SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Shape_ptr aSubShape, - SMESH::SMESH_Hypothesis_ptr anHyp) throw(SALOME::SALOME_Exception) +SMESH_Hypothesis::Hypothesis_Status + SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Shape_ptr aSubShape, + SMESH::SMESH_Hypothesis_ptr anHyp) { - MESSAGE("RemoveHypothesis"); + MESSAGE("removeHypothesis()"); // **** proposer liste de subShape (selection multiple) GEOM::GEOM_Shape_var mySubShape = GEOM::GEOM_Shape::_narrow(aSubShape); @@ -130,184 +522,335 @@ CORBA::Boolean SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp); if (CORBA::is_nil(myHyp)) - THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", + THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM); - bool ret = false; + SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK; try { TopoDS_Shape myLocSubShape = - _gen_i->_ShapeReader->GetShape(_geom, mySubShape); + _gen_i->GetShapeReader()->GetShape(SMESH_Gen_i::GetGeomEngine(), mySubShape); int hypId = myHyp->GetId(); - ret = _impl->RemoveHypothesis(myLocSubShape, hypId); + status = _impl->RemoveHypothesis(myLocSubShape, hypId); + if ( !SMESH_Hypothesis::IsStatusFatal(status) ) + _mapHypo.erase( hypId ); } catch(SALOME_Exception & S_ex) { THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); } - return ret; -}; + return status; +} -/** - *@TODO Not implemented +//============================================================================= +/*! + * */ +//============================================================================= + SMESH::ListOfHypothesis * SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Shape_ptr aSubShape) throw(SALOME::SALOME_Exception) { - MESSAGE("GetHypothesisList: Not implemented"); - return NULL; -}; + Unexpect aCatch(SALOME_SalomeException); + MESSAGE("GetHypothesisList"); + GEOM::GEOM_Shape_var mySubShape = GEOM::GEOM_Shape::_narrow(aSubShape); + if (CORBA::is_nil(mySubShape)) + THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", + SALOME::BAD_PARAM); + + SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis(); + + try { + TopoDS_Shape myLocSubShape + = _gen_i->GetShapeReader()->GetShape(SMESH_Gen_i::GetGeomEngine(), mySubShape); + + const list& aLocalList = _impl->GetHypothesisList( myLocSubShape ); + int i = 0, n = aLocalList.size(); + aList->length( n ); + + for ( list::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) { + SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt); + if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() ) + aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] ); + } + + aList->length( i ); + } + catch(SALOME_Exception & S_ex) { + THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); + } + + return aList._retn(); +} //============================================================================= /*! * */ //============================================================================= -SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetElementsOnShape(GEOM:: - GEOM_Shape_ptr aSubShape) throw(SALOME::SALOME_Exception) +SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Shape_ptr aSubShape, + const char* theName ) + throw(SALOME::SALOME_Exception) { - MESSAGE("SMESH_Mesh_i::GetElementsOnShape"); - GEOM::GEOM_Shape_var mySubShape = GEOM::GEOM_Shape::_narrow(aSubShape); - if (CORBA::is_nil(mySubShape)) - THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", - SALOME::BAD_PARAM); + Unexpect aCatch(SALOME_SalomeException); + MESSAGE("SMESH_Mesh_i::GetElementsOnShape"); + GEOM::GEOM_Shape_var mySubShape = GEOM::GEOM_Shape::_narrow(aSubShape); + if (CORBA::is_nil(mySubShape)) + THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", + SALOME::BAD_PARAM); + + int subMeshId = 0; + try { + TopoDS_Shape myLocSubShape + = _gen_i->GetShapeReader()->GetShape(SMESH_Gen_i::GetGeomEngine(), mySubShape); + + //Get or Create the SMESH_subMesh object implementation + + ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape); + subMeshId = mySubMesh->GetId(); + + // create a new subMesh object servant if there is none for the shape + + if (_mapSubMesh.find(subMeshId) == _mapSubMesh.end()) { + SMESH::SMESH_subMesh_var subMesh = createSubMesh( aSubShape ); + if ( _gen_i->CanPublishInStudy( subMesh ) ) { + SALOMEDS::SObject_var aSubmeshSO = _gen_i->PublishInStudy( _gen_i->GetCurrentStudy(), + SALOMEDS::SObject::_nil(), + subMesh, + theName ); + + // Add reference to to the study + SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); + SALOMEDS::SObject_var aShapeSO = aStudy->FindObjectIOR( SMESH_Gen_i::GetORB()->object_to_string( aSubShape ) ); + if ( !aSubmeshSO->_is_nil() && !aShapeSO->_is_nil() ) { + MESSAGE( "********** SMESH_Mesh_i::GetSubMesh(): adding shape reference..." ) + SALOMEDS::StudyBuilder_var aBuilder = aStudy->NewBuilder(); + SALOMEDS::SObject_var SO = aBuilder->NewObjectToTag( aSubmeshSO, SMESH_Gen_i::GetRefOnShapeTag() ); + aBuilder->Addreference( SO, aShapeSO ); + MESSAGE( "********** SMESH_Mesh_i::GetSubMesh(): shape reference added" ) + } + } + } + } + catch(SALOME_Exception & S_ex) { + THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); + } + + ASSERT(_mapSubMeshIor.find(subMeshId) != _mapSubMeshIor.end()); + return SMESH::SMESH_subMesh::_duplicate(_mapSubMeshIor[subMeshId]); +} - int subMeshId = 0; - try - { - SMESH_subMesh_i *subMeshServant; - TopoDS_Shape myLocSubShape - = _gen_i->_ShapeReader->GetShape(_geom, mySubShape); - //Get or Create the SMESH_subMesh object implementation +//============================================================================= +/*! + * + */ +//============================================================================= + +void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh ) + throw (SALOME::SALOME_Exception) +{ + MESSAGE("SMESH_Mesh_i::RemoveSubMesh"); + if ( theSubMesh->_is_nil() ) + return; + + GEOM::GEOM_Shape_var aSubShape; + SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); + if ( !aStudy->_is_nil() ) { + // Remove submesh's SObject + SALOMEDS::SObject_var anSO = SALOMEDS::SObject::_narrow( aStudy->FindObjectIOR( ( SMESH_Gen_i::GetORB()->object_to_string( theSubMesh ) ) ) ); + if ( !anSO->_is_nil() ) { + long aTag = SMESH_Gen_i::GetRefOnShapeTag(); + SALOMEDS::SObject_var anObj, aRef; + if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) ) + aSubShape = GEOM::GEOM_Shape::_narrow( aRef->GetObject() ); + + aStudy->NewBuilder()->RemoveObjectWithChildren( anSO ); + } + } + + removeSubMesh( theSubMesh, aSubShape.in() ); +} - ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape); - subMeshId = mySubMesh->GetId(); - // create a new subMesh object servant if there is none for the shape +//============================================================================= +/*! + * + */ +//============================================================================= - if (_mapSubMesh.find(subMeshId) != _mapSubMesh.end()) - { - ASSERT(_mapSubMesh_i.find(subMeshId) != _mapSubMesh_i.end()); - subMeshServant = _mapSubMesh_i[subMeshId]; - } - else - { - // create and activate the CORBA servant of Mesh - subMeshServant = new SMESH_subMesh_i(_gen_i, this, subMeshId); - SMESH::SMESH_subMesh_var subMesh - = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this()); - _mapSubMesh[subMeshId] = mySubMesh; - _mapSubMesh_i[subMeshId] = subMeshServant; - _mapSubMeshIor[subMeshId] - = SMESH::SMESH_subMesh::_duplicate(subMesh); - } - } - catch(SALOME_Exception & S_ex) - { - THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); - } +SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType, + const char* theName ) + throw(SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + SMESH::SMESH_Group_var aNewGroup = createGroup( theElemType, theName ); + + // Groups should be put under separate roots according to their type (nodes, edges, faces, volumes) + if ( _gen_i->CanPublishInStudy( aNewGroup ) ) { + SALOMEDS::SObject_var aGroupSO = _gen_i->PublishInStudy( _gen_i->GetCurrentStudy(), + SALOMEDS::SObject::_nil(), + aNewGroup, + theName ); + } + + return aNewGroup._retn(); +} - ASSERT(_mapSubMeshIor.find(subMeshId) != _mapSubMeshIor.end()); - return SMESH::SMESH_subMesh::_duplicate(_mapSubMeshIor[subMeshId]); -} - -/** - * Translate the UpdateAll SMESHDS_Command to a set of SMESH::log_command. - * As the input log need to be resized, it is realocated. - * @param logBlock The log where to insert created commands - * @param index The place where to insert created commands in log. It is updated - * with the place to put new elements. - * @return The realocated and resized log. - * @TODO Add support for other type of elements - */ -SMESH::log_array_var SMESH_Mesh_i:: - createUpdateAllCommand(SMESH::log_array_var log, int * index) -{ - MESSAGE("SMESH_Mesh_i::createUpdateAllCommand"); - SMESH::log_array_var aLog=new SMESH::log_array(log->length()+3); - aLog->length(log->length()+3); - - for(int i=0;i<*index;i++) - { - aLog[i]=log[i]; - } - - log->length(0); - int id=*index; - - //Remove all elements - aLog[id].commandType=SMESH::REMOVE_ALL; - id++; - - //Export nodes - aLog[id].commandType=SMESH::ADD_NODE; - aLog[id].number=_impl->GetMeshDS()->NbNodes(); - - double * nodesCoordinates=_impl->GetMeshDS()->getNodesCoordinates(); - aLog[id].coords=SMESH::double_array( - aLog[id].number*3, - aLog[id].number*3, - nodesCoordinates); - - long * nodesID=_impl->GetMeshDS()->getNodesID(); - aLog[id].indexes=SMESH::long_array( - aLog[id].number, - aLog[id].number, - nodesID); - - id++; - - MESSAGE("Export edges"); - //Export edges - aLog[id].commandType=SMESH::ADD_EDGE; - aLog[id].number=_impl->GetMeshDS()->NbEdges(); - aLog[id].coords.length(0); - - long * edgesIndices=_impl->GetMeshDS()->getEdgesIndices(); - aLog[id].indexes=SMESH::long_array( - aLog[id].number*3, - aLog[id].number*3, - edgesIndices); - - id++; - - MESSAGE("Export triangles"); - //Export triangles - aLog[id].commandType=SMESH::ADD_TRIANGLE; - aLog[id].number=_impl->GetMeshDS()->NbTriangles(); - aLog[id].coords.length(0); - - long * triasIndices=_impl->GetMeshDS()->getTrianglesIndices(); - aLog[id].indexes=SMESH::long_array( - aLog[id].number*4, - aLog[id].number*4, - triasIndices); - - (*index)=id; - return aLog; -} - -/** - * Return the log of the current mesh. CORBA wrap of the SMESH::GetLog method - * with a special treatment for SMESHDS_UpdateAll commands - * @param clearAfterGet Tell if the log must be cleared after being returned - * @return the log + +//============================================================================= +/*! + * */ +//============================================================================= + +void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_Group_ptr theGroup ) + throw (SALOME::SALOME_Exception) +{ + if ( theGroup->_is_nil() ) + return; + + SMESH_Group_i* aGroup = dynamic_cast( SMESH_Gen_i::GetServant( theGroup ).in() ); + if ( !aGroup ) + return; + + SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); + if ( !aStudy->_is_nil() ) { + // Remove group's SObject + SALOMEDS::SObject_var aGroupSO = SALOMEDS::SObject::_narrow( aStudy->FindObjectIOR( ( SMESH_Gen_i::GetORB()->object_to_string( theGroup ) ) ) ); + if ( !aGroupSO->_is_nil() ) + aStudy->NewBuilder()->RemoveObject( aGroupSO ); + } + + // Remove the group from SMESH data structures + removeGroup( aGroup->GetLocalID() ); +} + + +//============================================================================= +/*! + * + */ +//============================================================================= + +SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Shape_ptr theSubShape ) { + + TopoDS_Shape myLocSubShape = _gen_i->GetShapeReader()->GetShape(SMESH_Gen_i::GetGeomEngine(), theSubShape); + + ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape); + int subMeshId = mySubMesh->GetId(); + SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId); + SMESH::SMESH_subMesh_var subMesh + = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this()); + + _mapSubMesh[subMeshId] = mySubMesh; + _mapSubMesh_i[subMeshId] = subMeshServant; + _mapSubMeshIor[subMeshId] + = SMESH::SMESH_subMesh::_duplicate(subMesh); + + // register CORBA object for persistence + StudyContext* myStudyContext = _gen_i->GetCurrentStudyContext(); + string iorString = SMESH_Gen_i::GetORB()->object_to_string( subMesh ); + int nextId = myStudyContext->addObject( iorString ); + MESSAGE( "Add submesh to map with id = "<< nextId << " and IOR = " << iorString.c_str() ); + + return subMesh._retn(); +} + + +//============================================================================= +/*! + * + */ +//============================================================================= + +void SMESH_Mesh_i::removeSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh, GEOM::GEOM_Shape_ptr theSubShape ) +{ + MESSAGE("SMESH_Mesh_i::removeSubMesh()"); + if ( theSubMesh->_is_nil() || theSubShape->_is_nil() ) + return; + + try { + SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShape ); + for ( int i = 0, n = aHypList->length(); i < n; i++ ) { + removeHypothesis( theSubShape, aHypList[i] ); + } + } + catch( const SALOME::SALOME_Exception& ) { + MESSAGE("SMESH_Mesh_i::removeSubMesh(): exception caught!"); + } + + int subMeshId = theSubMesh->GetId(); + + _mapSubMesh.erase(subMeshId); + _mapSubMesh_i.erase(subMeshId); + _mapSubMeshIor.erase(subMeshId); + MESSAGE("SMESH_Mesh_i::removeSubMesh() completed"); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +SMESH::SMESH_Group_ptr SMESH_Mesh_i::createGroup( SMESH::ElementType theElemType, const char* theName ) +{ + int anId; + SMESH::SMESH_Group_var aGroup; + if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId ) ) { + SMESH_Group_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId ); + aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() ); + _mapGroups[anId] = SMESH::SMESH_Group::_duplicate( aGroup ); + + // register CORBA object for persistence + StudyContext* myStudyContext = _gen_i->GetCurrentStudyContext(); + string iorString = SMESH_Gen_i::GetORB()->object_to_string( aGroup ); + int nextId = myStudyContext->addObject( iorString ); + MESSAGE( "Add group to map with id = "<< nextId << " and IOR = " << iorString.c_str() ); + } + return aGroup._retn(); +} + + +//============================================================================= +/*! + * SMESH_Mesh_i::removeGroup + * + * Should be called by ~SMESH_Group_i() + */ +//============================================================================= + +void SMESH_Mesh_i::removeGroup( const int theId ) +{ + MESSAGE("SMESH_Mesh_i::removeGroup()" ); + if ( _mapGroups.find( theId ) != _mapGroups.end() ) { + _mapGroups.erase( theId ); + _impl->RemoveGroup( theId ); + } +} + + +//============================================================================= +/*! + * + */ +//============================================================================= + SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet) - throw(SALOME::SALOME_Exception) +throw(SALOME::SALOME_Exception) { MESSAGE("SMESH_Mesh_i::GetLog"); SMESH::log_array_var aLog; - /*try - {*/ + try + { list < SMESHDS_Command * >logDS = _impl->GetLog(); aLog = new SMESH::log_array; int indexLog = 0; int lg = logDS.size(); - MESSAGE("Number of command in the log: "<length(lg); list < SMESHDS_Command * >::iterator its = logDS.begin(); while (its != logDS.end()) @@ -326,38 +869,32 @@ SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet) //SCRUTE(rnum); list < double >::const_iterator ir = coordList.begin(); aLog[indexLog].commandType = comType; - if(comType==SMESHDS_UpdateAll) + aLog[indexLog].number = lgcom; + aLog[indexLog].coords.length(rnum); + aLog[indexLog].indexes.length(inum); + for (int i = 0; i < rnum; i++) { - aLog=createUpdateAllCommand(aLog, &indexLog); + aLog[indexLog].coords[i] = *ir; + //MESSAGE(" "<ClearLog(); - return aLog._retn(); - /*} + if (clearAfterGet) + _impl->ClearLog(); + } catch(SALOME_Exception & S_ex) { THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); - }*/ + } + return aLog._retn(); } // SMESH::string_array* SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet) @@ -498,7 +1035,8 @@ void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception) CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception) { - return _impl->GetId(); + MESSAGE("SMESH_Mesh_i::GetId"); + return _id; } //============================================================================= @@ -518,10 +1056,10 @@ CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception) */ //============================================================================= -::SMESH_Mesh & SMESH_Mesh_i::GetImpl() +void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl) { - MESSAGE("SMESH_Mesh_i::GetImpl()"); - return *_impl; + MESSAGE("SMESH_Mesh_i::SetImpl"); + _impl = impl; } //============================================================================= @@ -530,23 +1068,25 @@ CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception) */ //============================================================================= -GEOM::GEOM_Gen_ptr SMESH_Mesh_i::GetGeomEngine() +::SMESH_Mesh & SMESH_Mesh_i::GetImpl() { - MESSAGE("SMESH_Mesh_i::GetGeomEngine"); - return GEOM::GEOM_Gen::_duplicate(_geom); + MESSAGE("SMESH_Mesh_i::GetImpl()"); + return *_impl; } + //============================================================================= /*! * */ //============================================================================= -void SMESH_Mesh_i::SetIor(SMESH::SMESH_Mesh_ptr myIor) +SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor() { - MESSAGE("SMESH_Mesh_i::SetIor"); - _myIor = SMESH::SMESH_Mesh::_duplicate(myIor); - ASSERT(!CORBA::is_nil(_myIor)); + SMESH_MeshEditor_i *aMeshEditor = + new SMESH_MeshEditor_i(_impl->GetMeshDS()); + SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this(); + return aMesh._retn(); } //============================================================================= @@ -555,25 +1095,46 @@ void SMESH_Mesh_i::SetIor(SMESH::SMESH_Mesh_ptr myIor) */ //============================================================================= -SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetIor() +void SMESH_Mesh_i::ExportMED(const char *file, CORBA::Boolean auto_groups) throw(SALOME::SALOME_Exception) { - MESSAGE("SMESH_Mesh_i::GetIor"); - ASSERT(!CORBA::is_nil(_myIor)); - return SMESH::SMESH_Mesh::_duplicate(_myIor); + Unexpect aCatch(SALOME_SalomeException); + SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); + if ( aStudy->_is_nil() ) + return; + + char* aMeshName = NULL; + SALOMEDS::SObject_var aMeshSO = SALOMEDS::SObject::_narrow( aStudy->FindObjectIOR( ( SMESH_Gen_i::GetORB()->object_to_string( _this() ) ) ) ); + if ( !aMeshSO->_is_nil() ) + { + aMeshName = aMeshSO->GetName(); + //SCRUTE(file); + //SCRUTE(aMeshName); + //SCRUTE(aMeshSO->GetID()); + SALOMEDS::GenericAttribute_var anAttr; + SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder(); + SALOMEDS::AttributeExternalFileDef_var aFileName; + anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef"); + aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr); + ASSERT(!aFileName->_is_nil()); + aFileName->SetValue(file); + SALOMEDS::AttributeFileType_var aFileType; + anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType"); + aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr); + ASSERT(!aFileType->_is_nil()); + aFileType->SetValue("FICHIERMED"); + } + _impl->ExportMED( file, aMeshName, auto_groups ); } -//============================================================================= -/*! - * - */ -//============================================================================= - -SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor() +void SMESH_Mesh_i::ExportDAT(const char *file) throw(SALOME::SALOME_Exception) { - SMESH_MeshEditor_i *aMeshEditor = - new SMESH_MeshEditor_i(_impl->GetMeshDS()); - SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this(); - return aMesh._retn(); + Unexpect aCatch(SALOME_SalomeException); + _impl->ExportDAT(file); +} +void SMESH_Mesh_i::ExportUNV(const char *file) throw(SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + _impl->ExportUNV(file); } //============================================================================= @@ -584,6 +1145,7 @@ SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor() SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception) { + Unexpect aCatch(SALOME_SalomeException); SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this); SALOME_MED::MESH_var aMesh = aMedMesh->_this(); return aMesh._retn(); @@ -596,6 +1158,7 @@ SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception) //============================================================================= CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception) { + Unexpect aCatch(SALOME_SalomeException); return _impl->NbNodes(); } @@ -606,6 +1169,7 @@ CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception) //============================================================================= CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception) { + Unexpect aCatch(SALOME_SalomeException); return _impl->NbEdges(); } @@ -616,16 +1180,19 @@ CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception) //============================================================================= CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception) { + Unexpect aCatch(SALOME_SalomeException); return _impl->NbFaces(); } CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception) { + Unexpect aCatch(SALOME_SalomeException); return _impl->NbTriangles(); } CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception) { + Unexpect aCatch(SALOME_SalomeException); return _impl->NbQuadrangles(); } @@ -636,19 +1203,34 @@ CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception) //============================================================================= CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception) { + Unexpect aCatch(SALOME_SalomeException); return _impl->NbVolumes(); } CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception) { + Unexpect aCatch(SALOME_SalomeException); return _impl->NbTetras(); } CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception) { + Unexpect aCatch(SALOME_SalomeException); return _impl->NbHexas(); } +CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + return _impl->NbPyramids(); +} + +CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + return _impl->NbPrisms(); +} + //============================================================================= /*! * @@ -656,16 +1238,18 @@ CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception) //============================================================================= CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception) { + Unexpect aCatch(SALOME_SalomeException); return _impl->NbSubMesh(); } +//============================================================================= /*! - * Export mesh to a file - * @param fileName file name where to export the file - * @param fileType Currently it could be either "DAT", "UNV" or "MED". + * */ -void SMESH_Mesh_i::Export(const char* fileName, const char* fileType) - throw (SALOME::SALOME_Exception) +//============================================================================= +char* SMESH_Mesh_i::Dump() { - _impl->Export(fileName, fileType); + std::ostringstream os; + _impl->Dump( os ); + return CORBA::string_dup( os.str().c_str() ); } diff --git a/src/SMESH_I/SMESH_Mesh_i.hxx b/src/SMESH_I/SMESH_Mesh_i.hxx index 4942e7983..48243c177 100644 --- a/src/SMESH_I/SMESH_Mesh_i.hxx +++ b/src/SMESH_I/SMESH_Mesh_i.hxx @@ -31,46 +31,62 @@ #include #include CORBA_SERVER_HEADER(SMESH_Mesh) +#include CORBA_SERVER_HEADER(SMESH_Group) #include CORBA_SERVER_HEADER(SMESH_Hypothesis) #include CORBA_CLIENT_HEADER(GEOM_Gen) #include CORBA_CLIENT_HEADER(GEOM_Shape) #include CORBA_CLIENT_HEADER(MED) class SMESH_Gen_i; +class SMESH_Group_i; +#include "SMESH_Hypothesis.hxx" #include "SMESH_Mesh.hxx" -#include "SMESH_Gen_i.hxx" #include "SMESH_subMesh_i.hxx" #include "SMESH_subMesh.hxx" #include "SMESH_topo.hxx" #include +#include "SALOME_GenericObj_i.hh" + class SMESH_Mesh_i: - public POA_SMESH::SMESH_Mesh + public virtual POA_SMESH::SMESH_Mesh, + public virtual SALOME::GenericObj_i { public: - SMESH_Mesh_i(SMESH_Gen_i* myGen_i, - GEOM::GEOM_Gen_ptr geomEngine, - CORBA::Long studyId, - ::SMESH_Mesh * impl); + SMESH_Mesh_i(); + SMESH_Mesh_i( PortableServer::POA_ptr thePOA, + SMESH_Gen_i* myGen_i, + CORBA::Long studyId ); virtual ~SMESH_Mesh_i(); // --- CORBA + void SetShape( GEOM::GEOM_Shape_ptr theShape ) + throw (SALOME::SALOME_Exception); - CORBA::Boolean AddHypothesis(GEOM::GEOM_Shape_ptr aSubShape, - SMESH::SMESH_Hypothesis_ptr anHyp) + SMESH::Hypothesis_Status AddHypothesis(GEOM::GEOM_Shape_ptr aSubShape, + SMESH::SMESH_Hypothesis_ptr anHyp) throw (SALOME::SALOME_Exception); - CORBA::Boolean RemoveHypothesis(GEOM::GEOM_Shape_ptr aSubShape, - SMESH::SMESH_Hypothesis_ptr anHyp) + SMESH::Hypothesis_Status RemoveHypothesis(GEOM::GEOM_Shape_ptr aSubShape, + SMESH::SMESH_Hypothesis_ptr anHyp) throw (SALOME::SALOME_Exception); SMESH::ListOfHypothesis* GetHypothesisList(GEOM::GEOM_Shape_ptr aSubShape) throw (SALOME::SALOME_Exception); - SMESH::SMESH_subMesh_ptr GetElementsOnShape(GEOM::GEOM_Shape_ptr aSubShape) + SMESH::SMESH_subMesh_ptr GetSubMesh(GEOM::GEOM_Shape_ptr aSubShape, const char* theName) + throw (SALOME::SALOME_Exception); + + void RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh ) + throw (SALOME::SALOME_Exception); + + SMESH::SMESH_Group_ptr CreateGroup( SMESH::ElementType theElemType, const char* theName ) + throw (SALOME::SALOME_Exception); + + void RemoveGroup( SMESH::SMESH_Group_ptr theGroup ) throw (SALOME::SALOME_Exception); // SMESH::string_array* GetLog(CORBA::Boolean clearAfterGet) @@ -90,17 +106,25 @@ public: CORBA::Long GetStudyId() throw (SALOME::SALOME_Exception); - void Export(const char* fileName, const char* fileType) - throw (SALOME::SALOME_Exception); - // --- C++ interface void SetImpl(::SMESH_Mesh* impl); - ::SMESH_Mesh& GetImpl(); // :: force no namespace here - GEOM::GEOM_Gen_ptr GetGeomEngine(); - void SetIor(SMESH::SMESH_Mesh_ptr myIor); - SMESH::SMESH_Mesh_ptr GetIor(); + + SMESH_Gen_i* GetGen() { return _gen_i; } + + /*! + * consult DriverMED_R_SMESHDS_Mesh::ReadStatus for returned value + */ + SMESH::DriverMED_ReadStatus ImportMEDFile( const char* theFileName, const char* theMeshName ) + throw (SALOME::SALOME_Exception); + + void ExportMED( const char* file, CORBA::Boolean auto_groups ) + throw (SALOME::SALOME_Exception); + void ExportDAT( const char* file ) + throw (SALOME::SALOME_Exception); + void ExportUNV( const char* file ) + throw (SALOME::SALOME_Exception); SALOME_MED::MESH_ptr GetMEDMesh() throw (SALOME::SALOME_Exception); @@ -129,23 +153,49 @@ public: CORBA::Long NbHexas() throw (SALOME::SALOME_Exception); + CORBA::Long NbPyramids() + throw (SALOME::SALOME_Exception); + + CORBA::Long NbPrisms() + throw (SALOME::SALOME_Exception); + CORBA::Long NbSubMesh() throw (SALOME::SALOME_Exception); + + char* Dump(); + // Internal methods not available through CORBA + // They are called by corresponding interface methods + SMESH_Hypothesis::Hypothesis_Status addHypothesis(GEOM::GEOM_Shape_ptr aSubShape, + SMESH::SMESH_Hypothesis_ptr anHyp); + + SMESH_Hypothesis::Hypothesis_Status removeHypothesis(GEOM::GEOM_Shape_ptr aSubShape, + SMESH::SMESH_Hypothesis_ptr anHyp); + + bool setShape( GEOM::GEOM_Shape_ptr theShape ); + + int importMEDFile( const char* theFileName, const char* theMeshName ); + + SMESH::SMESH_subMesh_ptr createSubMesh( GEOM::GEOM_Shape_ptr theSubShape ); + + void removeSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh, GEOM::GEOM_Shape_ptr theSubShape ); + + SMESH::SMESH_Group_ptr createGroup( SMESH::ElementType theElemType, const char* theName ); + + void removeGroup( const int theId ); map _mapSubMesh_i; //NRI map _mapSubMesh; //NRI private: - SMESH::log_array_var createUpdateAllCommand(SMESH::log_array_var log, int * index); + static int myIdGenerator; ::SMESH_Mesh* _impl; // :: force no namespace here SMESH_Gen_i* _gen_i; - // CORBA::ORB_ptr _orb; -// SMESH_topo* _topo; // all local TopoDS_Shape of subShapes - GEOM::GEOM_Gen_var _geom; - CORBA::Long _studyId; - map _mapSubMeshIor; - SMESH::SMESH_Mesh_var _myIor; + int _id; // id given by creator (unique within the creator instance) + int _studyId; + map _mapSubMeshIor; + map _mapGroups; + map _mapHypo; }; #endif diff --git a/src/SMESH_I/SMESH_NETGEN_3D_i.cxx b/src/SMESH_I/SMESH_NETGEN_3D_i.cxx deleted file mode 100644 index 720ccefa5..000000000 --- a/src/SMESH_I/SMESH_NETGEN_3D_i.cxx +++ /dev/null @@ -1,60 +0,0 @@ -//============================================================================= -// File : SMESH_NETGEN_3D_i.cxx -// Created : Jeudi 31 Janvier 2003 -// Author : Nadir Bouhamou CEA -// Project : SALOME -// Copyright : CEA 2003 -// $Header$ -//============================================================================= -using namespace std; - -#include "SMESH_NETGEN_3D_i.hxx" -#include "SMESH_Gen.hxx" -#include "SMESH_HypothesisFactory.hxx" - -#include "Utils_CorbaException.hxx" -#include "utilities.h" - -//============================================================================= -/*! - * - */ -//============================================================================= - -SMESH_NETGEN_3D_i::SMESH_NETGEN_3D_i(const char* anHyp, - int studyId, - ::SMESH_Gen* genImpl) -{ - MESSAGE("SMESH_NETGEN_3D_i::SMESH_NETGEN_3D_i"); - _genImpl = genImpl; - ::SMESH_NETGEN_3D* impl - = new ::SMESH_NETGEN_3D(_genImpl->_hypothesisFactory.GetANewId(), - studyId, - genImpl); - SetImpl(impl); - _baseImpl = _impl; -} - -//============================================================================= -/*! - * - */ -//============================================================================= - -SMESH_NETGEN_3D_i::~SMESH_NETGEN_3D_i() -{ - MESSAGE("SMESH_NETGEN_3D_i::~SMESH_NETGEN_3D_i"); -} - -//============================================================================= -/*! - * - */ -//============================================================================= - -void SMESH_NETGEN_3D_i::SetImpl(::SMESH_NETGEN_3D* impl) -{ - MESSAGE("SMESH_NETGEN_3D_i::SetImpl"); - SMESH_3D_Algo_i::SetImpl(impl); - _impl = impl; -} diff --git a/src/SMESH_I/SMESH_NETGEN_3D_i.hxx b/src/SMESH_I/SMESH_NETGEN_3D_i.hxx deleted file mode 100644 index 68f4dd789..000000000 --- a/src/SMESH_I/SMESH_NETGEN_3D_i.hxx +++ /dev/null @@ -1,36 +0,0 @@ -//============================================================================= -// File : SMESH_NETGEN_3D_i.hxx -// Created : Jeudi 31 Janvier 2003 -// Author : Nadir Bouhamou CEA -// Project : SALOME -// Copyright : CEA 2003 -// $Header$ -//============================================================================= -#ifndef _SMESH_NETGEN_3D_I_HXX_ -#define _SMESH_NETGEN_3D_I_HXX_ - -#include -#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) - -#include "SMESH_3D_Algo_i.hxx" - -#include "SMESH_NETGEN_3D.hxx" - -class SMESH_NETGEN_3D_i: - public POA_SMESH::SMESH_NETGEN_3D, - public SMESH_3D_Algo_i -{ -public: - SMESH_NETGEN_3D_i(const char* anHyp, - int studyId, - ::SMESH_Gen* genImpl); - - virtual ~SMESH_NETGEN_3D_i(); - -protected: - virtual void SetImpl(::SMESH_NETGEN_3D* impl); - - ::SMESH_NETGEN_3D* _impl; -}; - -#endif diff --git a/src/SMESH_I/SMESH_subMesh_i.cxx b/src/SMESH_I/SMESH_subMesh_i.cxx index 3ed4d2965..8c6563ffd 100644 --- a/src/SMESH_I/SMESH_subMesh_i.cxx +++ b/src/SMESH_I/SMESH_subMesh_i.cxx @@ -35,6 +35,7 @@ using namespace std; #include "Utils_CorbaException.hxx" #include "utilities.h" #include "OpUtil.hxx" +#include "Utils_ExceptHandlers.hxx" //============================================================================= /*! @@ -43,6 +44,7 @@ using namespace std; //============================================================================= SMESH_subMesh_i::SMESH_subMesh_i() + : SALOME::GenericObj_i( PortableServer::POA::_nil() ) { MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i default, not for use"); ASSERT(0); @@ -54,14 +56,17 @@ SMESH_subMesh_i::SMESH_subMesh_i() */ //============================================================================= -SMESH_subMesh_i::SMESH_subMesh_i(SMESH_Gen_i* gen_i, - SMESH_Mesh_i* mesh_i, - int localId) +SMESH_subMesh_i::SMESH_subMesh_i( PortableServer::POA_ptr thePOA, + SMESH_Gen_i* gen_i, + SMESH_Mesh_i* mesh_i, + int localId ) + : SALOME::GenericObj_i( thePOA ) { MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i"); _gen_i = gen_i; _mesh_i = mesh_i; _localId = localId; + thePOA->activate_object( this ); // **** } //============================================================================= @@ -85,8 +90,16 @@ SMESH_subMesh_i::~SMESH_subMesh_i() CORBA::Long SMESH_subMesh_i::GetNumberOfElements() throw (SALOME::SALOME_Exception) { + Unexpect aCatch(SALOME_SalomeException); MESSAGE("SMESH_subMesh_i::GetNumberOfElements"); - // **** + if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() ) + return 0; + + SMESHDS_SubMesh* aSubMeshDS = _mesh_i->_mapSubMesh[_localId]->GetSubMeshDS(); + if ( aSubMeshDS == NULL ) + return 0; + + return aSubMeshDS->NbElements(); } //============================================================================= @@ -98,8 +111,16 @@ CORBA::Long SMESH_subMesh_i::GetNumberOfElements() CORBA::Long SMESH_subMesh_i::GetNumberOfNodes() throw (SALOME::SALOME_Exception) { + Unexpect aCatch(SALOME_SalomeException); MESSAGE("SMESH_subMesh_i::GetNumberOfNodes"); - // **** + if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() ) + return 0; + + SMESHDS_SubMesh* aSubMeshDS = _mesh_i->_mapSubMesh[_localId]->GetSubMeshDS(); + if ( aSubMeshDS == NULL ) + return 0; + + return aSubMeshDS->NbNodes(); } //============================================================================= @@ -111,8 +132,74 @@ CORBA::Long SMESH_subMesh_i::GetNumberOfNodes() SMESH::long_array* SMESH_subMesh_i::GetElementsId() throw (SALOME::SALOME_Exception) { + Unexpect aCatch(SALOME_SalomeException); MESSAGE("SMESH_subMesh_i::GetElementsId"); - // **** + SMESH::long_array_var aResult = new SMESH::long_array(); + + if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() ) + return aResult._retn(); + + SMESHDS_SubMesh* aSubMeshDS = _mesh_i->_mapSubMesh[_localId]->GetSubMeshDS(); + if ( aSubMeshDS == NULL ) + return aResult._retn(); + + aResult->length( aSubMeshDS->NbElements() ); + SMDS_ElemIteratorPtr anIt = aSubMeshDS->GetElements(); + for ( int i = 0, n = aSubMeshDS->NbElements(); i < n && anIt->more(); i++ ) + aResult[i] = anIt->next()->GetID(); + + return aResult._retn(); +} + + +//============================================================================= +/*! + * + */ +//============================================================================= + +SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theElemType ) + throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + MESSAGE("SMESH_subMesh_i::GetElementsByType"); + SMESH::long_array_var aResult = new SMESH::long_array(); + + if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() ) + return aResult._retn(); + + SMESHDS_SubMesh* aSubMeshDS = _mesh_i->_mapSubMesh[_localId]->GetSubMeshDS(); + if ( aSubMeshDS == NULL ) + return aResult._retn(); + + int i = 0; + if ( theElemType == SMESH::ALL ) + aResult->length( aSubMeshDS->NbElements() + aSubMeshDS->NbNodes() ); + else if ( theElemType == SMESH::NODE ) + aResult->length( aSubMeshDS->NbNodes() ); + else + aResult->length( aSubMeshDS->NbElements() ); + + int n = aResult->length(); + + if ( theElemType == SMESH::ALL || theElemType == SMESH::NODE ) { + SMDS_NodeIteratorPtr anIt = aSubMeshDS->GetNodes(); + while ( i < n && anIt->more() ) + aResult[i++] = anIt->next()->GetID(); + } + + if ( theElemType == SMESH::ALL || theElemType != SMESH::NODE ) { + SMDS_ElemIteratorPtr anIt = aSubMeshDS->GetElements(); + while ( i < n && anIt->more() ) { + const SMDS_MeshElement* anElem = anIt->next(); + if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType ) + aResult[i++] = anElem->GetID(); + } + } + + aResult->length( i ); + + return aResult._retn(); } //============================================================================= @@ -124,8 +211,23 @@ SMESH::long_array* SMESH_subMesh_i::GetElementsId() SMESH::long_array* SMESH_subMesh_i::GetNodesId() throw (SALOME::SALOME_Exception) { + Unexpect aCatch(SALOME_SalomeException); MESSAGE("SMESH_subMesh_i::GetNodesId"); - // **** + SMESH::long_array_var aResult = new SMESH::long_array(); + + if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() ) + return aResult._retn(); + + SMESHDS_SubMesh* aSubMeshDS = _mesh_i->_mapSubMesh[_localId]->GetSubMeshDS(); + if ( aSubMeshDS == NULL ) + return aResult._retn(); + + aResult->length( aSubMeshDS->NbNodes() ); + SMDS_NodeIteratorPtr anIt = aSubMeshDS->GetNodes(); + for ( int i = 0, n = aSubMeshDS->NbNodes(); i < n && anIt->more(); i++ ) + aResult[i] = anIt->next()->GetID(); + + return aResult._retn(); } //============================================================================= @@ -137,9 +239,9 @@ SMESH::long_array* SMESH_subMesh_i::GetNodesId() SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetFather() throw (SALOME::SALOME_Exception) { + Unexpect aCatch(SALOME_SalomeException); MESSAGE("SMESH_subMesh_i::GetFather"); - SMESH::SMESH_Mesh_var meshIor = _mesh_i->GetIor(); - return SMESH::SMESH_Mesh::_duplicate(meshIor); + return _mesh_i->_this(); } //============================================================================= @@ -162,6 +264,7 @@ CORBA::Long SMESH_subMesh_i::GetId() SALOME_MED::FAMILY_ptr SMESH_subMesh_i::GetFamily() throw (SALOME::SALOME_Exception) { + Unexpect aCatch(SALOME_SalomeException); SALOME_MED::MESH_var MEDMesh = GetFather()->GetMEDMesh(); SALOME_MED::Family_array_var families = diff --git a/src/SMESH_I/SMESH_subMesh_i.hxx b/src/SMESH_I/SMESH_subMesh_i.hxx index 0708405e5..9b456af4b 100644 --- a/src/SMESH_I/SMESH_subMesh_i.hxx +++ b/src/SMESH_I/SMESH_subMesh_i.hxx @@ -36,17 +36,21 @@ #include CORBA_CLIENT_HEADER(GEOM_Shape) #include CORBA_CLIENT_HEADER(MED) +#include "SALOME_GenericObj_i.hh" + class SMESH_Gen_i; class SMESH_Mesh_i; class SMESH_subMesh_i: - public POA_SMESH::SMESH_subMesh + public virtual POA_SMESH::SMESH_subMesh, + public virtual SALOME::GenericObj_i { public: SMESH_subMesh_i(); - SMESH_subMesh_i(SMESH_Gen_i* gen_i, - SMESH_Mesh_i* mesh_i, - int localId); + SMESH_subMesh_i( PortableServer::POA_ptr thePOA, + SMESH_Gen_i* gen_i, + SMESH_Mesh_i* mesh_i, + int localId ); ~SMESH_subMesh_i(); CORBA::Long GetNumberOfElements() @@ -57,6 +61,9 @@ public: SMESH::long_array* GetElementsId() throw (SALOME::SALOME_Exception); + + SMESH::long_array* GetElementsByType( SMESH::ElementType theElemType ) + throw (SALOME::SALOME_Exception); SMESH::long_array* GetNodesId() throw (SALOME::SALOME_Exception); diff --git a/src/SMESH_I/SMESH_test.py b/src/SMESH_I/SMESH_test.py index 3023a28d0..e823f9028 100644 --- a/src/SMESH_I/SMESH_test.py +++ b/src/SMESH_I/SMESH_test.py @@ -25,6 +25,8 @@ # Module : SMESH import SMESH +import StdMeshers + import smeshpy import salome from salome import sg @@ -76,41 +78,41 @@ ide=geompy.addToStudyInFather(face,edge,name) # ---- launch SMESH, init a Mesh with the box gen=smeshpy.smeshpy() -mesh=gen.Init(idb) +mesh=gen.CreateMesh(idb) # ---- create Hypothesis print "-------------------------- create Hypothesis" print "-------------------------- LocalLength" -hyp1=gen.CreateHypothesis("LocalLength") +hyp1=gen.CreateHypothesis("LocalLength","libStdMeshersEngine.so") print hyp1.GetName() print hyp1.GetId() -hypo1 = hyp1._narrow(SMESH.SMESH_LocalLength) +hypo1 = hyp1._narrow(StdMeshers.StdMeshers_LocalLength) print hypo1.GetLength() hypo1.SetLength(100) print hypo1.GetLength() print "-------------------------- bidon" -hyp3=gen.CreateHypothesis("bidon") +hyp3=gen.CreateHypothesis("bidon","") print "-------------------------- NumberOfSegments" -hyp3=gen.CreateHypothesis("NumberOfSegments") -hypo3=hyp3._narrow(SMESH.SMESH_NumberOfSegments) +hyp3=gen.CreateHypothesis("NumberOfSegments","libStdMeshersEngine.so") +hypo3=hyp3._narrow(StdMeshers.StdMeshers_NumberOfSegments) hypo3.SetNumberOfSegments(7) print hypo3.GetName() print hypo3.GetNumberOfSegments() print hypo3.GetId() print "-------------------------- MaxElementArea" -hyp4=gen.CreateHypothesis("MaxElementArea") -hypo4=hyp4._narrow(SMESH.SMESH_MaxElementArea) +hyp4=gen.CreateHypothesis("MaxElementArea","libStdMeshersEngine.so") +hypo4=hyp4._narrow(StdMeshers.StdMeshers_MaxElementArea) hypo4.SetMaxElementArea(5000) print hypo4.GetName() print hypo4.GetMaxElementArea() print hypo4.GetId() print "-------------------------- Regular_1D" -alg1=gen.CreateHypothesis("Regular_1D") +alg1=gen.CreateHypothesis("Regular_1D","libStdMeshersEngine.so") print alg1.GetName() print alg1.GetId() algo1=alg1._narrow(SMESH.SMESH_Algo) @@ -118,18 +120,18 @@ listHyp=algo1.GetCompatibleHypothesis() for hyp in listHyp: print hyp -algo_1=alg1._narrow(SMESH.SMESH_Regular_1D) +algo_1=alg1._narrow(StdMeshers.StdMeshers_Regular_1D) print algo_1.GetId() print "-------------------------- MEFISTO_2D" -alg2=gen.CreateHypothesis("MEFISTO_2D") +alg2=gen.CreateHypothesis("MEFISTO_2D","libStdMeshersEngine.so") print alg2.GetName() print alg2.GetId() algo2=alg2._narrow(SMESH.SMESH_Algo) listHyp=algo2.GetCompatibleHypothesis() for hyp in listHyp: print hyp -algo_2=alg2._narrow(SMESH.SMESH_MEFISTO_2D) +algo_2=alg2._narrow(StdMeshers.StdMeshers_MEFISTO_2D) print algo_2.GetId() # ---- add hypothesis to edge diff --git a/src/SMESH_I/smeshpy.py b/src/SMESH_I/smeshpy.py index ccc54cacf..9fb4709e7 100644 --- a/src/SMESH_I/smeshpy.py +++ b/src/SMESH_I/smeshpy.py @@ -44,14 +44,15 @@ class smeshpy: self._smesh = salome.lcc.FindOrLoadComponent("FactoryServer","SMESH") except: MESSAGE( "exception in smeshpy:__init__" ) - self._studyId = salome.myStudyId + self._study = salome.myStudy + self._smesh.SetCurrentStudy(self._study) #-------------------------------------------------------------------------- - def Init(self, shapeId): + def CreateMesh(self, shapeId): try: shape = salome.IDToObject(shapeId) - aMesh = self._smesh.Init(self._geom, self._studyId, shape) + aMesh = self._smesh.CreateMesh(shape) return aMesh except: MESSAGE( "exception in smeshpy:Init" ) @@ -59,9 +60,9 @@ class smeshpy: #-------------------------------------------------------------------------- - def CreateHypothesis(self, name): + def CreateHypothesis(self, name, libname): try: - hyp = self._smesh.CreateHypothesis(name,self._studyId) + hyp = self._smesh.CreateHypothesis(name, libname) return hyp except: MESSAGE( "exception in smeshpy:CreateHypothesis" ) diff --git a/src/SMESH_SWIG/Makefile.in b/src/SMESH_SWIG/Makefile.in index eea0f73c2..343100a93 100644 --- a/src/SMESH_SWIG/Makefile.in +++ b/src/SMESH_SWIG/Makefile.in @@ -43,6 +43,7 @@ EXPORT_PYSCRIPTS = libSMESH_Swig.py \ SMESH_test1.py \ SMESH_test2.py \ SMESH_test3.py \ + SMESH_test4.py \ SMESH_mechanic.py \ SMESH_mechanic_tetra.py \ SMESH_fixation.py \ @@ -53,12 +54,10 @@ EXPORT_PYSCRIPTS = libSMESH_Swig.py \ SMESH_box2_tetra.py \ SMESH_box3_tetra.py \ SMESH_flight_skin.py \ - SMESH_Partition1_tetra.py \ - SMESH_box_hexa.py \ - SMESH_demo_hexa2.py \ - SMESH_demo_hexa.py \ - SMESH_demo_tetra2.py \ - SMESH_demo_tetra.py + SMESH_Partition1_tetra.py\ + batchmode_mefisto.py \ + SMESH_controls.py \ + SMESH_freebord.py LIB_CLIENT_IDL = SALOMEDS.idl \ SALOME_Exception.idl \ @@ -68,14 +67,16 @@ LIB_CLIENT_IDL = SALOMEDS.idl \ SMESH_Mesh.idl \ SMESH_Hypothesis.idl \ SMESH_BasicHypothesis.idl \ + SMESH_Group.idl \ SALOME_ModuleCatalog.idl \ SALOME_Component.idl \ + SALOME_GenericObj.idl \ MED.idl EXPORT_SHAREDPYSCRIPTS=SMESH_shared_modules.py CPPFLAGS+=$(QT_INCLUDES) $(PYTHON_INCLUDES) $(OCC_INCLUDES) $(VTK_INCLUDES) $(OGL_INCLUDES) -DHAVE_CONFIG_H LIBS+= $(PYTHON_LIBS) -LDFLAGS+= -lSMESHGUI +LDFLAGS+= -lSMESHGUI -L${KERNEL_ROOT_DIR}/lib/salome -lSalomeGenericObj @CONCLUDE@ diff --git a/src/SMESH_SWIG/SMESH_Partition1_tetra.py b/src/SMESH_SWIG/SMESH_Partition1_tetra.py index 1478f01b7..fd72c8e18 100644 --- a/src/SMESH_SWIG/SMESH_Partition1_tetra.py +++ b/src/SMESH_SWIG/SMESH_Partition1_tetra.py @@ -1,245 +1,227 @@ -# -# Tetrahedrization of the geometry generated by the Python script GEOM_Partition1.py -# Hypothesis and algorithms for the mesh generation are global -# -#%Make geometry (like CEA script (A1)) using Partition algorithm% from OCC -# -- Rayon de la bariere - -barier_height = 7.0 -barier_radius = 5.6 / 2 # Rayon de la bariere -colis_radius = 1.0 / 2 # Rayon du colis -colis_step = 2.0 # Distance s‰parant deux colis -cc_width = 0.11 # Epaisseur du complement de colisage - -# -- - -cc_radius = colis_radius + cc_width -from math import sqrt -colis_center = sqrt(2.0)*colis_step/2 - -# -- - -import geompy -geom = geompy.geom - -boolean_common = 1 -boolean_cut = 2 -boolean_fuse = 3 -boolean_section = 4 - -# -- - -barier = geompy.MakeCylinder( - geom.MakePointStruct(0.,0.,0.), - geom.MakeDirection(geom.MakePointStruct(0.,0.,1.)), - barier_radius, - barier_height) - -# -- - -colis = geompy.MakeCylinder( - geom.MakePointStruct(0.,0.,0.), - geom.MakeDirection(geom.MakePointStruct(0.,0.,1.)), - colis_radius, - barier_height) - -cc = geompy.MakeCylinder( - geom.MakePointStruct(0.,0.,0.), - geom.MakeDirection(geom.MakePointStruct(0.,0.,1.)), - cc_radius, - barier_height) - -colis_cc = geompy.MakeCompound( - [colis._get_Name(), cc._get_Name()]) - -colis_cc = geompy.MakeTranslation( - colis_cc, colis_center, 0.0, 0.0) - -colis_cc_multi = geompy.MakeMultiRotation1D( - colis_cc, - geom.MakeDirection(geom.MakePointStruct(0.,0.,1.)), - geom.MakePointStruct(0.,0.,0.), - 4) - -# -- - -alveole = geompy.Partition( - [colis_cc_multi._get_Name(), barier._get_Name()]) - -ShapeTypeShell = 3 -ShapeTypeFace = 4 -ShapeTypeEdge = 6 - -print "Analysis of the geometry to mesh (right after the Partition) :" - -subShellList=geompy.SubShapeAll(alveole,ShapeTypeShell) -subFaceList=geompy.SubShapeAll(alveole,ShapeTypeFace) -subEdgeList=geompy.SubShapeAll(alveole,ShapeTypeEdge) - -print "number of Shells in alveole : ",len(subShellList) -print "number of Faces in alveole : ",len(subFaceList) -print "number of Edges in alveole : ",len(subEdgeList) - -subshapes = geompy.SubShapeAll( alveole, geompy.ShapeType["SHAPE"] ) - -## there are 9 subshapes - -comp1 = geompy.MakeCompound( [ subshapes[0]._get_Name(), subshapes[1]._get_Name() ] ); -comp2 = geompy.MakeCompound( [ subshapes[2]._get_Name(), subshapes[3]._get_Name() ] ); -comp3 = geompy.MakeCompound( [ subshapes[4]._get_Name(), subshapes[5]._get_Name() ] ); -comp4 = geompy.MakeCompound( [ subshapes[6]._get_Name(), subshapes[7]._get_Name() ] ); - -compIORs = [] -compIORs.append( comp1._get_Name() ); -compIORs.append( comp2._get_Name() ); -compIORs.append( comp3._get_Name() ); -compIORs.append( comp4._get_Name() ); -comp = geompy.MakeCompound( compIORs ); - -alveole = geompy.MakeCompound( [ comp._get_Name(), subshapes[8]._get_Name() ]); - -idalveole= geompy.addToStudy(alveole, "alveole") - -print "Analysis of the geometry to mesh (right after the MakeCompound) :" - -subShellList=geompy.SubShapeAll(alveole,ShapeTypeShell) -subFaceList=geompy.SubShapeAll(alveole,ShapeTypeFace) -subEdgeList=geompy.SubShapeAll(alveole,ShapeTypeEdge) - -print "number of Shells in alveole : ",len(subShellList) -print "number of Faces in alveole : ",len(subFaceList) -print "number of Edges in alveole : ",len(subEdgeList) - -status=geompy.CheckShape(alveole) -print " check status ", status - -# ---- launch SMESH - -import salome -from salome import sg - -import SMESH -import smeshpy - -smeshgui = salome.ImportComponentGUI("SMESH") -smeshgui.Init(salome.myStudyId) - -gen=smeshpy.smeshpy() - -# ---- create Hypothesis - -print "-------------------------- create Hypothesis (In this case global hypothesis are used)" - -print "-------------------------- NumberOfSegments" - -numberOfSegments = 10 - -hyp1=gen.CreateHypothesis("NumberOfSegments") -hypNbSeg=hyp1._narrow(SMESH.SMESH_NumberOfSegments) -hypNbSeg.SetNumberOfSegments(numberOfSegments) -hypNbSegID = hypNbSeg.GetId() -print hypNbSeg.GetName() -print hypNbSegID -print hypNbSeg.GetNumberOfSegments() - -idseg = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypNbSeg) ) -smeshgui.SetName(idseg, "NumberOfSegments") - -print "-------------------------- MaxElementArea" - -maxElementArea = 0.1 - -hyp2=gen.CreateHypothesis("MaxElementArea") -hypArea=hyp2._narrow(SMESH.SMESH_MaxElementArea) -hypArea.SetMaxElementArea(maxElementArea) -print hypArea.GetName() -print hypArea.GetId() -print hypArea.GetMaxElementArea() - -idarea = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypArea) ) -smeshgui.SetName(idarea, "MaxElementArea") - -print "-------------------------- MaxElementVolume" - -maxElementVolume = 0.5 - -hyp3=gen.CreateHypothesis("MaxElementVolume") -hypVolume=hyp3._narrow(SMESH.SMESH_MaxElementVolume) -hypVolume.SetMaxElementVolume(maxElementVolume) -print hypVolume.GetName() -print hypVolume.GetId() -print hypVolume.GetMaxElementVolume() - -idvolume = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypVolume) ) -smeshgui.SetName(idvolume, "MaxElementVolume") - -# ---- create Algorithms - -print "-------------------------- create Algorithms" - -print "-------------------------- Regular_1D" - -hypothesis=gen.CreateHypothesis("Regular_1D") -regular1D = hypothesis._narrow(SMESH.SMESH_Regular_1D) -regularID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(regular1D) ) -smeshgui.SetName(regularID, "Wire Discretisation") - -print "-------------------------- MEFISTO_2D" - -hypothesis=gen.CreateHypothesis("MEFISTO_2D") -mefisto2D = hypothesis._narrow(SMESH.SMESH_MEFISTO_2D) -mefistoID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(mefisto2D) ) -smeshgui.SetName(mefistoID, "MEFISTO_2D") - -print "-------------------------- NETGEN_3D" - -hypothesis=gen.CreateHypothesis("NETGEN_3D") -netgen3D = hypothesis._narrow(SMESH.SMESH_NETGEN_3D) -netgenID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(netgen3D) ) -smeshgui.SetName(netgenID, "NETGEN_3D") - -# ---- init a Mesh with the alveole - -mesh=gen.Init(idalveole) -idmesh = smeshgui.AddNewMesh( salome.orb.object_to_string(mesh) ) -smeshgui.SetName(idmesh, "MeshAlveole") -smeshgui.SetShape(idalveole, idmesh) - -# ---- add hypothesis to alveole - -print "-------------------------- add hypothesis to alveole" - -ret=mesh.AddHypothesis(alveole,regular1D) -print ret -ret=mesh.AddHypothesis(alveole,hypNbSeg) -print ret -ret=mesh.AddHypothesis(alveole,mefisto2D) -print ret -ret=mesh.AddHypothesis(alveole,hypArea) -print ret -ret=mesh.AddHypothesis(alveole,netgen3D) -print ret -ret=mesh.AddHypothesis(alveole,hypVolume) -print ret - -smeshgui.SetAlgorithms( idmesh, regularID) -smeshgui.SetHypothesis( idmesh, idseg ) -smeshgui.SetAlgorithms( idmesh, mefistoID ) -smeshgui.SetHypothesis( idmesh, idarea ) -smeshgui.SetAlgorithms( idmesh, netgenID ) -smeshgui.SetHypothesis( idmesh, idvolume ) - -sg.updateObjBrowser(1) - - -print "-------------------------- compute the mesh of alveole " -ret=gen.Compute(mesh,idalveole) -print ret -if ret != 0: - log=mesh.GetLog(0) # no erase trace - for linelog in log: - print linelog -else: - print "problem when computing the mesh" - -sg.updateObjBrowser(1) +# +# Tetrahedrization of the geometry generated by the Python script GEOM_Partition1.py +# Hypothesis and algorithms for the mesh generation are global +# +#%Make geometry (like CEA script (A1)) using Partition algorithm% from OCC +# -- Rayon de la bariere + +import salome +import geompy + +import StdMeshers +import NETGENPlugin + +geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM") +smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH") + +geom.GetCurrentStudy(salome.myStudy._get_StudyId()) +smesh.SetCurrentStudy(salome.myStudy) + +smeshgui = salome.ImportComponentGUI("SMESH") +smeshgui.Init(salome.myStudyId); + +#--------------------------------------------------------------- + +barier_height = 7.0 +barier_radius = 5.6 / 2 # Rayon de la bariere +colis_radius = 1.0 / 2 # Rayon du colis +colis_step = 2.0 # Distance s‰parant deux colis +cc_width = 0.11 # Epaisseur du complement de colisage + +# -- + +cc_radius = colis_radius + cc_width +from math import sqrt +colis_center = sqrt(2.0)*colis_step/2 + +# -- + +boolean_common = 1 +boolean_cut = 2 +boolean_fuse = 3 +boolean_section = 4 + +# -- + +barier = geompy.MakeCylinder( + geom.MakePointStruct(0.,0.,0.), + geom.MakeDirection(geom.MakePointStruct(0.,0.,1.)), + barier_radius, + barier_height) + +# -- + +colis = geompy.MakeCylinder( + geom.MakePointStruct(0.,0.,0.), + geom.MakeDirection(geom.MakePointStruct(0.,0.,1.)), + colis_radius, + barier_height) + +cc = geompy.MakeCylinder( + geom.MakePointStruct(0.,0.,0.), + geom.MakeDirection(geom.MakePointStruct(0.,0.,1.)), + cc_radius, + barier_height) + +colis_cc = geompy.MakeCompound( + [colis._get_Name(), cc._get_Name()]) + +colis_cc = geompy.MakeTranslation( + colis_cc, colis_center, 0.0, 0.0) + +colis_cc_multi = geompy.MakeMultiRotation1D( + colis_cc, + geom.MakeDirection(geom.MakePointStruct(0.,0.,1.)), + geom.MakePointStruct(0.,0.,0.), + 4) + +# -- + +alveole = geompy.Partition( + [colis_cc_multi._get_Name(), barier._get_Name()]) + +ShapeTypeShell = 3 +ShapeTypeFace = 4 +ShapeTypeEdge = 6 + +print "Analysis of the geometry to mesh (right after the Partition) :" + +subShellList=geompy.SubShapeAll(alveole,ShapeTypeShell) +subFaceList=geompy.SubShapeAll(alveole,ShapeTypeFace) +subEdgeList=geompy.SubShapeAll(alveole,ShapeTypeEdge) + +print "number of Shells in alveole : ",len(subShellList) +print "number of Faces in alveole : ",len(subFaceList) +print "number of Edges in alveole : ",len(subEdgeList) + +subshapes = geompy.SubShapeAll( alveole, geompy.ShapeType["SHAPE"] ) + +## there are 9 subshapes + +comp1 = geompy.MakeCompound( [ subshapes[0]._get_Name(), subshapes[1]._get_Name() ] ); +comp2 = geompy.MakeCompound( [ subshapes[2]._get_Name(), subshapes[3]._get_Name() ] ); +comp3 = geompy.MakeCompound( [ subshapes[4]._get_Name(), subshapes[5]._get_Name() ] ); +comp4 = geompy.MakeCompound( [ subshapes[6]._get_Name(), subshapes[7]._get_Name() ] ); + +compIORs = [] +compIORs.append( comp1._get_Name() ); +compIORs.append( comp2._get_Name() ); +compIORs.append( comp3._get_Name() ); +compIORs.append( comp4._get_Name() ); +comp = geompy.MakeCompound( compIORs ); + +alveole = geompy.MakeCompound( [ comp._get_Name(), subshapes[8]._get_Name() ]); + +idalveole= geompy.addToStudy(alveole, "alveole") + +print "Analysis of the geometry to mesh (right after the MakeCompound) :" + +subShellList=geompy.SubShapeAll(alveole,ShapeTypeShell) +subFaceList=geompy.SubShapeAll(alveole,ShapeTypeFace) +subEdgeList=geompy.SubShapeAll(alveole,ShapeTypeEdge) + +print "number of Shells in alveole : ",len(subShellList) +print "number of Faces in alveole : ",len(subFaceList) +print "number of Edges in alveole : ",len(subEdgeList) + +status=geompy.CheckShape(alveole) +print " check status ", status + +# ---- launch SMESH + +# ---- create Hypothesis + +print "-------------------------- create Hypothesis (In this case global hypothesis are used)" + +print "-------------------------- NumberOfSegments" + +numberOfSegments = 10 + +hypNbSeg=smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so") +hypNbSeg.SetNumberOfSegments(numberOfSegments) +print hypNbSeg.GetName() +print hypNbSeg.GetId() +print hypNbSeg.GetNumberOfSegments() + +smeshgui.SetName(salome.ObjectToID(hypNbSeg), "NumberOfSegments_10") + +print "-------------------------- MaxElementArea" + +maxElementArea = 0.1 + +hypArea=smesh.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so") +hypArea.SetMaxElementArea(maxElementArea) +print hypArea.GetName() +print hypArea.GetId() +print hypArea.GetMaxElementArea() + +smeshgui.SetName(salome.ObjectToID(hypArea), "MaxElementArea_0.1") + +print "-------------------------- MaxElementVolume" + +maxElementVolume = 0.5 + +hypVolume=smesh.CreateHypothesis("MaxElementVolume", "libStdMeshersEngine.so") +hypVolume.SetMaxElementVolume(maxElementVolume) +print hypVolume.GetName() +print hypVolume.GetId() +print hypVolume.GetMaxElementVolume() + +smeshgui.SetName(salome.ObjectToID(hypVolume), "MaxElementVolume_0.5") + +# ---- create Algorithms + +print "-------------------------- create Algorithms" + +print "-------------------------- Regular_1D" + +regular1D = smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so") +smeshgui.SetName(salome.ObjectToID(regular1D), "Wire Discretisation") + +print "-------------------------- MEFISTO_2D" + +mefisto2D=smesh.CreateHypothesis("MEFISTO_2D", "libStdMeshersEngine.so") +smeshgui.SetName(salome.ObjectToID(mefisto2D), "MEFISTO_2D") + +print "-------------------------- NETGEN_3D" + +netgen3D=smesh.CreateHypothesis("NETGEN_3D", "libNETGENEngine.so") +smeshgui.SetName(salome.ObjectToID(netgen3D), "NETGEN_3D") + +# ---- init a Mesh with the alveole +shape_mesh = salome.IDToObject( idalveole ) + +mesh=smesh.CreateMesh(shape_mesh) +smeshgui.SetName(salome.ObjectToID(mesh), "MeshAlveole") + +# ---- add hypothesis to alveole + +print "-------------------------- add hypothesis to alveole" + +mesh.AddHypothesis(shape_mesh,regular1D) +mesh.AddHypothesis(shape_mesh,hypNbSeg) + +mesh.AddHypothesis(shape_mesh,mefisto2D) +mesh.AddHypothesis(shape_mesh,hypArea) + +mesh.AddHypothesis(shape_mesh,netgen3D) +mesh.AddHypothesis(shape_mesh,hypVolume) + +print "-------------------------- compute the mesh of alveole " +ret=smesh.Compute(mesh,shape_mesh) + +if ret != 0: + log=mesh.GetLog(0) # no erase trace + for linelog in log: + print linelog + print "Information about the Mesh_mechanic:" + print "Number of nodes : ", mesh.NbNodes() + print "Number of edges : ", mesh.NbEdges() + print "Number of faces : ", mesh.NbFaces() + print "Number of triangles : ", mesh.NbTriangles() + print "Number of volumes: ", mesh.NbVolumes() + print "Number of tetrahedrons: ", mesh.NbTetras() +else: + print "problem when computing the mesh" + +salome.sg.updateObjBrowser(1) diff --git a/src/SMESH_SWIG/SMESH_box2_tetra.py b/src/SMESH_SWIG/SMESH_box2_tetra.py index 6db29ba29..d5e6979f6 100644 --- a/src/SMESH_SWIG/SMESH_box2_tetra.py +++ b/src/SMESH_SWIG/SMESH_box2_tetra.py @@ -4,15 +4,16 @@ # import salome -from salome import sg - import geompy -import SMESH -import smeshpy +import StdMeshers +import NETGENPlugin + +geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM") +smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH") -geom = geompy.geom -myBuilder = geompy.myBuilder +smeshgui = salome.ImportComponentGUI("SMESH") +smeshgui.Init(salome.myStudyId); ShapeTypeShell = 3 ShapeTypeFace = 4 @@ -65,12 +66,8 @@ print "number of Shells in shell : ",len(subShellList) print "number of Faces in shell : ",len(subFaceList) print "number of Edges in shell : ",len(subEdgeList) -# ---- launch SMESH - -smeshgui = salome.ImportComponentGUI("SMESH") -smeshgui.Init(salome.myStudyId) -gen=smeshpy.smeshpy() +### ---------------------------- SMESH -------------------------------------- # ---- create Hypothesis @@ -80,44 +77,40 @@ print "-------------------------- NumberOfSegments" numberOfSegments = 10 -hyp1=gen.CreateHypothesis("NumberOfSegments") -hypNbSeg=hyp1._narrow(SMESH.SMESH_NumberOfSegments) +hypNbSeg=smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so") hypNbSeg.SetNumberOfSegments(numberOfSegments) -hypNbSegID = hypNbSeg.GetId() + print hypNbSeg.GetName() -print hypNbSegID +print hypNbSeg.GetId() print hypNbSeg.GetNumberOfSegments() -idseg = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypNbSeg) ) -smeshgui.SetName(idseg, "NumberOfSegments") +smeshgui.SetName(salome.ObjectToID(hypNbSeg), "NumberOfSegments_10") print "-------------------------- MaxElementArea" maxElementArea = 500 -hyp2=gen.CreateHypothesis("MaxElementArea") -hypArea=hyp2._narrow(SMESH.SMESH_MaxElementArea) +hypArea=smesh.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so") hypArea.SetMaxElementArea(maxElementArea) + print hypArea.GetName() print hypArea.GetId() print hypArea.GetMaxElementArea() -idarea = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypArea) ) -smeshgui.SetName(idarea, "MaxElementArea") +smeshgui.SetName(salome.ObjectToID(hypArea), "MaxElementArea_500") print "-------------------------- MaxElementVolume" maxElementVolume = 500 -hyp3=gen.CreateHypothesis("MaxElementVolume") -hypVolume=hyp3._narrow(SMESH.SMESH_MaxElementVolume) +hypVolume=smesh.CreateHypothesis("MaxElementVolume", "libStdMeshersEngine.so") hypVolume.SetMaxElementVolume(maxElementVolume) + print hypVolume.GetName() print hypVolume.GetId() print hypVolume.GetMaxElementVolume() -idvolume = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypVolume) ) -smeshgui.SetName(idvolume, "MaxElementVolume") +smeshgui.SetName(salome.ObjectToID(hypVolume), "MaxElementVolume_500") # ---- create Algorithms @@ -125,65 +118,52 @@ print "-------------------------- create Algorithms" print "-------------------------- Regular_1D" -hypothesis=gen.CreateHypothesis("Regular_1D") -regular1D = hypothesis._narrow(SMESH.SMESH_Regular_1D) -regularID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(regular1D) ) -smeshgui.SetName(regularID, "Wire Discretisation") +regular1D=smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so") +smeshgui.SetName(salome.ObjectToID(regular1D), "Wire Discretisation") print "-------------------------- MEFISTO_2D" -hypothesis=gen.CreateHypothesis("MEFISTO_2D") -mefisto2D = hypothesis._narrow(SMESH.SMESH_MEFISTO_2D) -mefistoID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(mefisto2D) ) -smeshgui.SetName(mefistoID, "MEFISTO_2D") +mefisto2D=smesh.CreateHypothesis("MEFISTO_2D", "libStdMeshersEngine.so") +smeshgui.SetName(salome.ObjectToID(mefisto2D), "MEFISTO_2D") print "-------------------------- NETGEN_3D" -hypothesis=gen.CreateHypothesis("NETGEN_3D") -netgen3D = hypothesis._narrow(SMESH.SMESH_NETGEN_3D) -netgenID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(netgen3D) ) -smeshgui.SetName(netgenID, "NETGEN_3D") +netgen3D=smesh.CreateHypothesis("NETGEN_3D", "libNETGENEngine.so") +smeshgui.SetName(salome.ObjectToID(netgen3D), "NETGEN_3D") # ---- init a Mesh with the shell -mesh=gen.Init(idshell) -idmesh = smeshgui.AddNewMesh( salome.orb.object_to_string(mesh) ) -smeshgui.SetName(idmesh, "MeshBox2") -smeshgui.SetShape(idshell, idmesh) +mesh = smesh.CreateMesh(shell) +smeshgui.SetName(salome.ObjectToID(mesh), "MeshBox2") # ---- add hypothesis to shell print "-------------------------- add hypothesis to shell" -ret=mesh.AddHypothesis(shell,regular1D) -print ret -ret=mesh.AddHypothesis(shell,hypNbSeg) -print ret -ret=mesh.AddHypothesis(shell,mefisto2D) -print ret -ret=mesh.AddHypothesis(shell,hypArea) -print ret -ret=mesh.AddHypothesis(shell,netgen3D) -print ret -ret=mesh.AddHypothesis(shell,hypVolume) -print ret +mesh.AddHypothesis(shell,regular1D) +mesh.AddHypothesis(shell,hypNbSeg) -smeshgui.SetAlgorithms( idmesh, regularID) -smeshgui.SetHypothesis( idmesh, idseg ) -smeshgui.SetAlgorithms( idmesh, mefistoID ) -smeshgui.SetHypothesis( idmesh, idarea ) -smeshgui.SetAlgorithms( idmesh, netgenID ) -smeshgui.SetHypothesis( idmesh, idvolume ) +mesh.AddHypothesis(shell,mefisto2D) +mesh.AddHypothesis(shell,hypArea) -sg.updateObjBrowser(1) +mesh.AddHypothesis(shell,netgen3D) +mesh.AddHypothesis(shell,hypVolume) +salome.sg.updateObjBrowser(1) print "-------------------------- compute shell" -ret=gen.Compute(mesh,idshell) +ret= smesh.Compute(mesh,shell) print ret -log=mesh.GetLog(0) # no erase trace -for linelog in log: - print linelog - - -sg.updateObjBrowser(1) +if ret != 0: + log=mesh.GetLog(0) # no erase trace + for linelog in log: + print linelog + print "Information about the MeshBox2:" + print "Number of nodes : ", mesh.NbNodes() + print "Number of edges : ", mesh.NbEdges() + print "Number of faces : ", mesh.NbFaces() + print "Number of triangles : ", mesh.NbTriangles() + print "Number of volumes : ", mesh.NbVolumes() + print "Number of tetrahedrons: ", mesh.NbTetras() +else: + print "probleme when computing the mesh" diff --git a/src/SMESH_SWIG/SMESH_box3_tetra.py b/src/SMESH_SWIG/SMESH_box3_tetra.py index 000a2611b..adb7d4944 100644 --- a/src/SMESH_SWIG/SMESH_box3_tetra.py +++ b/src/SMESH_SWIG/SMESH_box3_tetra.py @@ -5,15 +5,16 @@ # import salome -from salome import sg - import geompy -import SMESH -import smeshpy +import StdMeshers +import NETGENPlugin + +geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM") +smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH") -geom = geompy.geom -myBuilder = geompy.myBuilder +smeshgui = salome.ImportComponentGUI("SMESH") +smeshgui.Init(salome.myStudyId); ShapeTypeShell = 3 ShapeTypeFace = 4 @@ -77,12 +78,8 @@ print "number of Shells in shell : ",len(subShellList) print "number of Faces in shell : ",len(subFaceList) print "number of Edges in shell : ",len(subEdgeList) -# ---- launch SMESH - -smeshgui = salome.ImportComponentGUI("SMESH") -smeshgui.Init(salome.myStudyId) -gen=smeshpy.smeshpy() +### ---------------------------- SMESH -------------------------------------- # ---- create Hypothesis @@ -92,44 +89,40 @@ print "-------------------------- NumberOfSegments" numberOfSegments = 10 -hyp1=gen.CreateHypothesis("NumberOfSegments") -hypNbSeg=hyp1._narrow(SMESH.SMESH_NumberOfSegments) +hypNbSeg=smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so") hypNbSeg.SetNumberOfSegments(numberOfSegments) -hypNbSegID = hypNbSeg.GetId() + print hypNbSeg.GetName() -print hypNbSegID +print hypNbSeg.GetId() print hypNbSeg.GetNumberOfSegments() -idseg = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypNbSeg) ) -smeshgui.SetName(idseg, "NumberOfSegments") +smeshgui.SetName(salome.ObjectToID(hypNbSeg), "NumberOfSegments_10") print "-------------------------- MaxElementArea" maxElementArea = 500 -hyp2=gen.CreateHypothesis("MaxElementArea") -hypArea=hyp2._narrow(SMESH.SMESH_MaxElementArea) +hypArea=smesh.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so") hypArea.SetMaxElementArea(maxElementArea) + print hypArea.GetName() print hypArea.GetId() print hypArea.GetMaxElementArea() -idarea = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypArea) ) -smeshgui.SetName(idarea, "MaxElementArea") +smeshgui.SetName(salome.ObjectToID(hypArea), "MaxElementArea_500") print "-------------------------- MaxElementVolume" maxElementVolume = 500 -hyp3=gen.CreateHypothesis("MaxElementVolume") -hypVolume=hyp3._narrow(SMESH.SMESH_MaxElementVolume) +hypVolume=smesh.CreateHypothesis("MaxElementVolume", "libStdMeshersEngine.so") hypVolume.SetMaxElementVolume(maxElementVolume) + print hypVolume.GetName() print hypVolume.GetId() print hypVolume.GetMaxElementVolume() -idvolume = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypVolume) ) -smeshgui.SetName(idvolume, "MaxElementVolume") +smeshgui.SetName(salome.ObjectToID(hypVolume), "MaxElementVolume_500") # ---- create Algorithms @@ -137,65 +130,52 @@ print "-------------------------- create Algorithms" print "-------------------------- Regular_1D" -hypothesis=gen.CreateHypothesis("Regular_1D") -regular1D = hypothesis._narrow(SMESH.SMESH_Regular_1D) -regularID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(regular1D) ) -smeshgui.SetName(regularID, "Wire Discretisation") +regular1D=smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so") +smeshgui.SetName(salome.ObjectToID(regular1D), "Wire Discretisation") print "-------------------------- MEFISTO_2D" -hypothesis=gen.CreateHypothesis("MEFISTO_2D") -mefisto2D = hypothesis._narrow(SMESH.SMESH_MEFISTO_2D) -mefistoID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(mefisto2D) ) -smeshgui.SetName(mefistoID, "MEFISTO_2D") +mefisto2D=smesh.CreateHypothesis("MEFISTO_2D", "libStdMeshersEngine.so") +smeshgui.SetName(salome.ObjectToID(mefisto2D), "MEFISTO_2D") print "-------------------------- NETGEN_3D" -hypothesis=gen.CreateHypothesis("NETGEN_3D") -netgen3D = hypothesis._narrow(SMESH.SMESH_NETGEN_3D) -netgenID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(netgen3D) ) -smeshgui.SetName(netgenID, "NETGEN_3D") +netgen3D=smesh.CreateHypothesis("NETGEN_3D", "libNETGENEngine.so") +smeshgui.SetName(salome.ObjectToID(netgen3D), "NETGEN_3D") # ---- init a Mesh with the shell -mesh=gen.Init(idshell) -idmesh = smeshgui.AddNewMesh( salome.orb.object_to_string(mesh) ) -smeshgui.SetName(idmesh, "MeshBox2") -smeshgui.SetShape(idshell, idmesh) +mesh = smesh.CreateMesh(shell) +smeshgui.SetName(salome.ObjectToID(mesh), "MeshBox3") # ---- add hypothesis to shell print "-------------------------- add hypothesis to shell" -ret=mesh.AddHypothesis(shell,regular1D) -print ret -ret=mesh.AddHypothesis(shell,hypNbSeg) -print ret -ret=mesh.AddHypothesis(shell,mefisto2D) -print ret -ret=mesh.AddHypothesis(shell,hypArea) -print ret -ret=mesh.AddHypothesis(shell,netgen3D) -print ret -ret=mesh.AddHypothesis(shell,hypVolume) -print ret +mesh.AddHypothesis(shell,regular1D) +mesh.AddHypothesis(shell,hypNbSeg) -smeshgui.SetAlgorithms( idmesh, regularID) -smeshgui.SetHypothesis( idmesh, idseg ) -smeshgui.SetAlgorithms( idmesh, mefistoID ) -smeshgui.SetHypothesis( idmesh, idarea ) -smeshgui.SetAlgorithms( idmesh, netgenID ) -smeshgui.SetHypothesis( idmesh, idvolume ) +mesh.AddHypothesis(shell,mefisto2D) +mesh.AddHypothesis(shell,hypArea) -sg.updateObjBrowser(1) +mesh.AddHypothesis(shell,netgen3D) +mesh.AddHypothesis(shell,hypVolume) +salome.sg.updateObjBrowser(1) print "-------------------------- compute shell" -ret=gen.Compute(mesh,idshell) +ret= smesh.Compute(mesh,shell) print ret -log=mesh.GetLog(0) # no erase trace -for linelog in log: - print linelog - - -sg.updateObjBrowser(1) +if ret != 0: + log=mesh.GetLog(0) # no erase trace + for linelog in log: + print linelog + print "Information about the MeshBox3:" + print "Number of nodes : ", mesh.NbNodes() + print "Number of edges : ", mesh.NbEdges() + print "Number of faces : ", mesh.NbFaces() + print "Number of triangles : ", mesh.NbTriangles() + print "Number of volumes : ", mesh.NbVolumes() + print "Number of tetrahedrons: ", mesh.NbTetras() +else: + print "probleme when computing the mesh" diff --git a/src/SMESH_SWIG/SMESH_box_tetra.py b/src/SMESH_SWIG/SMESH_box_tetra.py index 99744949e..38effb777 100644 --- a/src/SMESH_SWIG/SMESH_box_tetra.py +++ b/src/SMESH_SWIG/SMESH_box_tetra.py @@ -4,21 +4,18 @@ # import salome -from salome import sg - import geompy -import SMESH -import smeshpy - -# ----------------------------------------------------------------------------- +import StdMeshers +import NETGENPlugin -##geom = salome.lcc.FindOrLoadComponent("FactoryServer", "Geometry") -##myBuilder = salome.myStudy.NewBuilder() +geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM") +smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH") -geom = geompy.geom -myBuilder = geompy.myBuilder +smeshgui = salome.ImportComponentGUI("SMESH") +smeshgui.Init(salome.myStudyId); +# ----------------------------------------------------------------------------- ShapeTypeShell = 3 ShapeTypeFace = 4 ShapeTypeEdge = 6 @@ -38,12 +35,8 @@ print "number of Shells in box : ",len(subShellList) print "number of Faces in box : ",len(subFaceList) print "number of Edges in box : ",len(subEdgeList) -# ---- launch SMESH -smeshgui = salome.ImportComponentGUI("SMESH") -smeshgui.Init(salome.myStudyId) - -gen=smeshpy.smeshpy() +### ---------------------------- SMESH -------------------------------------- # ---- create Hypothesis @@ -53,44 +46,40 @@ print "-------------------------- NumberOfSegments" numberOfSegments = 10 -hyp1=gen.CreateHypothesis("NumberOfSegments") -hypNbSeg=hyp1._narrow(SMESH.SMESH_NumberOfSegments) +hypNbSeg=smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so") hypNbSeg.SetNumberOfSegments(numberOfSegments) -hypNbSegID = hypNbSeg.GetId() + print hypNbSeg.GetName() -print hypNbSegID +print hypNbSeg.GetId() print hypNbSeg.GetNumberOfSegments() -idseg = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypNbSeg) ) -smeshgui.SetName(idseg, "NumberOfSegments") +smeshgui.SetName(salome.ObjectToID(hypNbSeg), "NumberOfSegments_10") print "-------------------------- MaxElementArea" maxElementArea = 500 -hyp2=gen.CreateHypothesis("MaxElementArea") -hypArea=hyp2._narrow(SMESH.SMESH_MaxElementArea) +hypArea=smesh.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so") hypArea.SetMaxElementArea(maxElementArea) + print hypArea.GetName() print hypArea.GetId() print hypArea.GetMaxElementArea() -idarea = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypArea) ) -smeshgui.SetName(idarea, "MaxElementArea") +smeshgui.SetName(salome.ObjectToID(hypArea), "MaxElementArea_500") print "-------------------------- MaxElementVolume" maxElementVolume = 500 -hyp3=gen.CreateHypothesis("MaxElementVolume") -hypVolume=hyp3._narrow(SMESH.SMESH_MaxElementVolume) +hypVolume=smesh.CreateHypothesis("MaxElementVolume", "libStdMeshersEngine.so") hypVolume.SetMaxElementVolume(maxElementVolume) + print hypVolume.GetName() print hypVolume.GetId() print hypVolume.GetMaxElementVolume() -idvolume = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypVolume) ) -smeshgui.SetName(idvolume, "MaxElementVolume") +smeshgui.SetName(salome.ObjectToID(hypVolume), "MaxElementVolume_500") # ---- create Algorithms @@ -98,65 +87,52 @@ print "-------------------------- create Algorithms" print "-------------------------- Regular_1D" -hypothesis=gen.CreateHypothesis("Regular_1D") -regular1D = hypothesis._narrow(SMESH.SMESH_Regular_1D) -regularID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(regular1D) ) -smeshgui.SetName(regularID, "Wire Discretisation") +regular1D=smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so") +smeshgui.SetName(salome.ObjectToID(regular1D), "Wire Discretisation") print "-------------------------- MEFISTO_2D" -hypothesis=gen.CreateHypothesis("MEFISTO_2D") -mefisto2D = hypothesis._narrow(SMESH.SMESH_MEFISTO_2D) -mefistoID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(mefisto2D) ) -smeshgui.SetName(mefistoID, "MEFISTO_2D") +mefisto2D=smesh.CreateHypothesis("MEFISTO_2D", "libStdMeshersEngine.so") +smeshgui.SetName(salome.ObjectToID(mefisto2D), "MEFISTO_2D") print "-------------------------- NETGEN_3D" -hypothesis=gen.CreateHypothesis("NETGEN_3D") -netgen3D = hypothesis._narrow(SMESH.SMESH_NETGEN_3D) -netgenID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(netgen3D) ) -smeshgui.SetName(netgenID, "NETGEN_3D") +netgen3D=smesh.CreateHypothesis("NETGEN_3D", "libNETGENEngine.so") +smeshgui.SetName(salome.ObjectToID(netgen3D), "NETGEN_3D") # ---- init a Mesh with the boxe -mesh=gen.Init(idbox) -idmesh = smeshgui.AddNewMesh( salome.orb.object_to_string(mesh) ) -smeshgui.SetName(idmesh, "MeshBox") -smeshgui.SetShape(idbox, idmesh) +mesh = smesh.CreateMesh(box) +smeshgui.SetName(salome.ObjectToID(mesh), "MeshBox") # ---- add hypothesis to the boxe -print "-------------------------- add hypothesis to the boxe" +print "-------------------------- add hypothesis to the box" -ret=mesh.AddHypothesis(box,regular1D) -print ret -ret=mesh.AddHypothesis(box,hypNbSeg) -print ret -ret=mesh.AddHypothesis(box,mefisto2D) -print ret -ret=mesh.AddHypothesis(box,hypArea) -print ret -ret=mesh.AddHypothesis(box,netgen3D) -print ret -ret=mesh.AddHypothesis(box,hypVolume) -print ret +mesh.AddHypothesis(box,regular1D) +mesh.AddHypothesis(box,hypNbSeg) -smeshgui.SetAlgorithms( idmesh, regularID) -smeshgui.SetHypothesis( idmesh, idseg ) -smeshgui.SetAlgorithms( idmesh, mefistoID ) -smeshgui.SetHypothesis( idmesh, idarea ) -smeshgui.SetAlgorithms( idmesh, netgenID ) -smeshgui.SetHypothesis( idmesh, idvolume ) +mesh.AddHypothesis(box,mefisto2D) +mesh.AddHypothesis(box,hypArea) -sg.updateObjBrowser(1) +mesh.AddHypothesis(box,netgen3D) +mesh.AddHypothesis(box,hypVolume) +salome.sg.updateObjBrowser(1) print "-------------------------- compute the mesh of the boxe" -ret=gen.Compute(mesh,idbox) +ret=smesh.Compute(mesh,box) print ret -log=mesh.GetLog(0) # no erase trace -for linelog in log: - print linelog - - -sg.updateObjBrowser(1) +if ret != 0: + log=mesh.GetLog(0) # no erase trace + for linelog in log: + print linelog + print "Information about the MeshBox:" + print "Number of nodes : ", mesh.NbNodes() + print "Number of edges : ", mesh.NbEdges() + print "Number of faces : ", mesh.NbFaces() + print "Number of triangles : ", mesh.NbTriangles() + print "Number of volumes : ", mesh.NbVolumes() + print "Number of tetrahedrons: ", mesh.NbTetras() +else: + print "probleme when computing the mesh" diff --git a/src/SMESH_SWIG/SMESH_controls.py b/src/SMESH_SWIG/SMESH_controls.py new file mode 100644 index 000000000..83c950178 --- /dev/null +++ b/src/SMESH_SWIG/SMESH_controls.py @@ -0,0 +1,227 @@ +# Copyright (C) 2004 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +# +# +# +# File : SMESH_control.py +# Author : Sergey LITONIN +# Module : SMESH + + +import SMESH +import SMESH_mechanic + +smesh = SMESH_mechanic.smesh +mesh = SMESH_mechanic.mesh +salome = SMESH_mechanic.salome + + +aFilterMgr = smesh.CreateFilterManager() + +# Criterion : AREA > 100 + +aFunctor = aFilterMgr.CreateArea() +aPredicate = aFilterMgr.CreateMoreThan() +aPredicate.SetNumFunctor( aFunctor ) +aPredicate.SetMargin( 100 ) + +aFilter = aFilterMgr.CreateFilter() +aFilter.SetPredicate( aPredicate ) + +anIds = aFilter.GetElementsId( mesh ) + +# print result +print "Criterion: Area > 100 Nb = ", len( anIds ) +#for i in range( len( anIds ) ): + #print anIds[ i ] + +# create group +aGroup = mesh.CreateGroup( SMESH.FACE, "Area > 100" ) +aGroup.Add( anIds ) + + +# Criterion : Taper > 3e-15 + +aFunctor = aFilterMgr.CreateTaper() +aPredicate = aFilterMgr.CreateMoreThan() +aPredicate.SetNumFunctor( aFunctor ) +aPredicate.SetMargin( 3e-15 ) + +aFilter = aFilterMgr.CreateFilter() +aFilter.SetPredicate( aPredicate ) + +anIds = aFilter.GetElementsId( mesh ) + +# print result +print "Criterion: Taper > 3e-15 Nb = ", len( anIds ) +#for i in range( len( anIds ) ): + #print anIds[ i ] + +# create group +aGroup = mesh.CreateGroup( SMESH.FACE, "Taper > 3e-15" ) +aGroup.Add( anIds ) + + +# Criterion : ASPECT RATIO > 1.3 + +aFunctor = aFilterMgr.CreateAspectRatio() +aPredicate = aFilterMgr.CreateMoreThan() +aPredicate.SetNumFunctor( aFunctor ) +aPredicate.SetMargin( 1.3 ) + +aFilter = aFilterMgr.CreateFilter() +aFilter.SetPredicate( aPredicate ) + +anIds = aFilter.GetElementsId( mesh ) + +# print result +print "Criterion: Aspect Ratio > 1.3 Nb = ", len( anIds ) +#for i in range( len( anIds ) ): + #print anIds[ i ] + +# create group +aGroup = mesh.CreateGroup( SMESH.FACE, "Aspect Ratio > 1.3" ) +aGroup.Add( anIds ) + + +# Criterion : MINIMUM ANGLE < 30 + +aFunctor = aFilterMgr.CreateMinimumAngle() +aPredicate = aFilterMgr.CreateLessThan() +aPredicate.SetNumFunctor( aFunctor ) +aPredicate.SetMargin( 30 ) + +aFilter = aFilterMgr.CreateFilter() +aFilter.SetPredicate( aPredicate ) + +anIds = aFilter.GetElementsId( mesh ) + +# print result +print "Criterion: Minimum Angle < 30 Nb = ", len( anIds ) +#for i in range( len( anIds ) ): + #print anIds[ i ] + +# create group +aGroup = mesh.CreateGroup( SMESH.FACE, "Minimum Angle < 30" ) +aGroup.Add( anIds ) + +# Criterion : Warp > 2e-13 + +aFunctor = aFilterMgr.CreateWarping() +aPredicate = aFilterMgr.CreateMoreThan() +aPredicate.SetNumFunctor( aFunctor ) +aPredicate.SetMargin( 2e-13 ) + +aFilter = aFilterMgr.CreateFilter() +aFilter.SetPredicate( aPredicate ) + +anIds = aFilter.GetElementsId( mesh ) + +# print result +print "Criterion: Warp > 2e-13 Nb = ", len( anIds ) +#for i in range( len( anIds ) ): + #print anIds[ i ] + +# create group +aGroup = mesh.CreateGroup( SMESH.FACE, "Warp > 2e-13" ) +aGroup.Add( anIds ) + +# Criterion : Skew > 18 + +aFunctor = aFilterMgr.CreateSkew() +aPredicate = aFilterMgr.CreateMoreThan() +aPredicate.SetNumFunctor( aFunctor ) +aPredicate.SetMargin( 18 ) + +aFilter = aFilterMgr.CreateFilter() +aFilter.SetPredicate( aPredicate ) + +anIds = aFilter.GetElementsId( mesh ) + +# print result +print "Criterion: Skew > 18 Nb = ", len( anIds ) +#for i in range( len( anIds ) ): + #print anIds[ i ] + +# create group +aGroup = mesh.CreateGroup( SMESH.FACE, "Skew > 18" ) +aGroup.Add( anIds ) + +# Criterion : Length > 10 + +aFunctor = aFilterMgr.CreateLength() +aPredicate = aFilterMgr.CreateMoreThan() +aPredicate.SetNumFunctor( aFunctor ) +aPredicate.SetMargin( 10 ) + +aFilter = aFilterMgr.CreateFilter() +aFilter.SetPredicate( aPredicate ) + +anIds = aFilter.GetElementsId( mesh ) + +# print result +print "Criterion: Length > 10 Nb = ", len( anIds ) +#for i in range( len( anIds ) ): + #print anIds[ i ] + +# create group +aGroup = mesh.CreateGroup( SMESH.EDGE, "Length > 10" ) +aGroup.Add( anIds ) + +# Criterion : Borders at multi-connections = 2 + +aFunctor = aFilterMgr.CreateMultiConnection() +aPredicate = aFilterMgr.CreateEqualTo() +aPredicate.SetNumFunctor( aFunctor ) +aPredicate.SetMargin( 2 ) + +aFilter = aFilterMgr.CreateFilter() +aFilter.SetPredicate( aPredicate ) + +anIds = aFilter.GetElementsId( mesh ) + +# print result +print "Criterion: Borders at multi-connections = 2 Nb = ", len( anIds ) +#for i in range( len( anIds ) ): + #print anIds[ i ] + +# create group +aGroup = mesh.CreateGroup( SMESH.EDGE, "Borders at multi-connections = 2" ) +aGroup.Add( anIds ) + + +salome.sg.updateObjBrowser(1) + + + + + + + + + + + + + + + + + + diff --git a/src/SMESH_SWIG/SMESH_fixation.py b/src/SMESH_SWIG/SMESH_fixation.py index 93accf52e..9158ee567 100644 --- a/src/SMESH_SWIG/SMESH_fixation.py +++ b/src/SMESH_SWIG/SMESH_fixation.py @@ -25,14 +25,10 @@ # $Header$ import salome -from salome import sg - import geompy - import math geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM") -myBuilder = salome.myStudy.NewBuilder() ShapeTypeCompSolid = 1 ShapeTypeSolid = 2 @@ -290,9 +286,10 @@ cylcongy0 = geom.MakeCylinder(pcyly0, vx, rayonConge, longueurPlq +2*marge) bcong1=geom.MakeBoolean(bcong1,cylcongx0,2) bcong2=geom.MakeBoolean(bcong2,cylcongx0,2) bcong1=geom.MakeBoolean(bcong1,cylcongy0,2) +#NRI : inverse order of BOP +bcong3=geom.MakeBoolean(bcong3,cylcongy0,2) bcong3=geom.MakeBoolean(bcong3,cylcongx3,2) bcong4=geom.MakeBoolean(bcong4,cylcongx3,2) -bcong3=geom.MakeBoolean(bcong3,cylcongy0,2) pf1 = geom.MakePointStruct(0., y0h, z3) pf2 = geom.MakePointStruct(0., y1, z3) diff --git a/src/SMESH_SWIG/SMESH_fixation_hexa.py b/src/SMESH_SWIG/SMESH_fixation_hexa.py index 2916e6a09..2d12c7f47 100644 --- a/src/SMESH_SWIG/SMESH_fixation_hexa.py +++ b/src/SMESH_SWIG/SMESH_fixation_hexa.py @@ -5,14 +5,13 @@ # import SMESH_fixation -import SMESH -import smeshpy + +import StdMeshers compshell = SMESH_fixation.compshell idcomp = SMESH_fixation.idcomp geompy = SMESH_fixation.geompy salome = SMESH_fixation.salome -sg = SMESH_fixation.sg ShapeTypeShell = 3 ShapeTypeFace = 4 @@ -30,13 +29,12 @@ print "number of Edges in compshell : ",len(subEdgeList) status=geompy.CheckShape(compshell) print " check status ", status -### ---- launch SMESH +### ---------------------------- SMESH -------------------------------------- +smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH") smeshgui = salome.ImportComponentGUI("SMESH") smeshgui.Init(salome.myStudyId) -gen=smeshpy.smeshpy() - ### ---- create Hypothesis print "-------------------------- create Hypothesis" @@ -45,16 +43,14 @@ print "-------------------------- NumberOfSegments" numberOfSegments = 5 -hyp1=gen.CreateHypothesis("NumberOfSegments") -hypNbSeg=hyp1._narrow(SMESH.SMESH_NumberOfSegments) +hypNbSeg=smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so") hypNbSeg.SetNumberOfSegments(numberOfSegments) -hypNbSegID = hypNbSeg.GetId() + print hypNbSeg.GetName() -print hypNbSegID +print hypNbSeg.GetId() print hypNbSeg.GetNumberOfSegments() -idseg = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypNbSeg) ) -smeshgui.SetName(idseg, "NumberOfSegments") +smeshgui.SetName(salome.ObjectToID(hypNbSeg), "NumberOfSegments_5") # ---- create Algorithms @@ -62,61 +58,54 @@ print "-------------------------- create Algorithms" print "-------------------------- Regular_1D" -hypothesis=gen.CreateHypothesis("Regular_1D") -regular1D = hypothesis._narrow(SMESH.SMESH_Regular_1D) -regularID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(regular1D) ) -smeshgui.SetName(regularID, "Wire Discretisation") +regular1D=smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so") + +smeshgui.SetName(salome.ObjectToID(regular1D), "Wire Discretisation") print "-------------------------- Quadrangle_2D" -hypothesis=gen.CreateHypothesis("Quadrangle_2D") -quad2D = hypothesis._narrow(SMESH.SMESH_Quadrangle_2D) -quadID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(quad2D) ) -smeshgui.SetName(quadID, "Quadrangle_2D") +quad2D=smesh.CreateHypothesis("Quadrangle_2D", "libStdMeshersEngine.so") + +smeshgui.SetName(salome.ObjectToID(quad2D), "Quadrangle_2D") print "-------------------------- Hexa_3D" -hypothesis=gen.CreateHypothesis("Hexa_3D") -hexa3D = hypothesis._narrow(SMESH.SMESH_Hexa_3D) -hexaID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(hexa3D) ) -smeshgui.SetName(hexaID, "Hexa_3D") +hexa3D=smesh.CreateHypothesis("Hexa_3D", "libStdMeshersEngine.so") + +smeshgui.SetName(salome.ObjectToID(hexa3D), "Hexa_3D") # ---- init a Mesh with the compshell +shape_mesh = salome.IDToObject( idcomp ) + +mesh=smesh.CreateMesh(shape_mesh) +smeshgui.SetName(salome.ObjectToID(mesh), "MeshCompShell") -mesh=gen.Init(idcomp) -idmesh = smeshgui.AddNewMesh( salome.orb.object_to_string(mesh) ) -smeshgui.SetName(idmesh, "MeshcompShel") -smeshgui.SetShape(idcomp, idmesh) # ---- add hypothesis to compshell print "-------------------------- add hypothesis to compshell" -ret=mesh.AddHypothesis(compshell,regular1D) -print ret -ret=mesh.AddHypothesis(compshell,hypNbSeg) -print ret -ret=mesh.AddHypothesis(compshell,quad2D) -print ret -ret=mesh.AddHypothesis(compshell,hexa3D) -print ret - -smeshgui.SetAlgorithms( idmesh, regularID) -smeshgui.SetHypothesis( idmesh, idseg ) -smeshgui.SetAlgorithms( idmesh, quadID ) -smeshgui.SetAlgorithms( idmesh, hexaID ) +mesh.AddHypothesis(shape_mesh,regular1D) +mesh.AddHypothesis(shape_mesh,hypNbSeg) -sg.updateObjBrowser(1) +mesh.AddHypothesis(shape_mesh,quad2D) +mesh.AddHypothesis(shape_mesh,hexa3D) +salome.sg.updateObjBrowser(1) print "-------------------------- compute compshell" -ret=gen.Compute(mesh,idcomp) +ret=smesh.Compute(mesh, shape_mesh) print ret if ret != 0: log=mesh.GetLog(0) # no erase trace for linelog in log: print linelog + print "Information about the MeshcompShel:" + print "Number of nodes : ", mesh.NbNodes() + print "Number of edges : ", mesh.NbEdges() + print "Number of faces : ", mesh.NbFaces() + print "Number of quadrangles : ", mesh.NbQuadrangles() + print "Number of volumes : ", mesh.NbVolumes() + print "Number of hexahedrons : ", mesh.NbHexas() else: print "problem when Computing the mesh" - -sg.updateObjBrowser(1) diff --git a/src/SMESH_SWIG/SMESH_fixation_tetra.py b/src/SMESH_SWIG/SMESH_fixation_tetra.py index 57e9c913d..d429fe958 100644 --- a/src/SMESH_SWIG/SMESH_fixation_tetra.py +++ b/src/SMESH_SWIG/SMESH_fixation_tetra.py @@ -4,15 +4,14 @@ # Hypothesis and algorithms for the mesh generation are global # +import StdMeshers +import NETGENPlugin import SMESH_fixation -import SMESH -import smeshpy compshell = SMESH_fixation.compshell idcomp = SMESH_fixation.idcomp geompy = SMESH_fixation.geompy salome = SMESH_fixation.salome -sg = SMESH_fixation.sg ShapeTypeShell = 3 ShapeTypeFace = 4 @@ -30,13 +29,12 @@ print "number of Edges in compshell : ",len(subEdgeList) status=geompy.CheckShape(compshell) print " check status ", status -### ---- launch SMESH +### ---------------------------- SMESH -------------------------------------- +smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH") smeshgui = salome.ImportComponentGUI("SMESH") smeshgui.Init(salome.myStudyId) -gen=smeshpy.smeshpy() - ### ---- create Hypothesis print "-------------------------- create Hypothesis" @@ -45,44 +43,41 @@ print "-------------------------- NumberOfSegments" numberOfSegments = 5 -hypothesis=gen.CreateHypothesis("NumberOfSegments") -hypNbSeg=hypothesis._narrow(SMESH.SMESH_NumberOfSegments) +hypNbSeg=smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so") hypNbSeg.SetNumberOfSegments(numberOfSegments) -hypNbSegID = hypNbSeg.GetId() + print hypNbSeg.GetName() -print hypNbSegID +print hypNbSeg.GetId() print hypNbSeg.GetNumberOfSegments() -idseg = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypNbSeg) ) -smeshgui.SetName(idseg, "NumberOfSegments") +smeshgui.SetName(salome.ObjectToID(hypNbSeg), "NumberOfSegments_5") print "-------------------------- MaxElementArea" -maxElementArea = 80 +## maxElementArea = 80 -hypothesis=gen.CreateHypothesis("MaxElementArea") -hypArea=hypothesis._narrow(SMESH.SMESH_MaxElementArea) -hypArea.SetMaxElementArea(maxElementArea) -print hypArea.GetName() -print hypArea.GetId() -print hypArea.GetMaxElementArea() +## hypArea=smesh.CreateHypothesis("MaxElementArea") +## hypArea.SetMaxElementArea(maxElementArea) +## print hypArea.GetName() +## print hypArea.GetId() +## print hypArea.GetMaxElementArea() +## smeshgui.SetName(salome.ObjectToID(hypArea), "MaxElementArea_160") +hypLengthFromEdges=smesh.CreateHypothesis("LengthFromEdges", "libStdMeshersEngine.so") +smeshgui.SetName(salome.ObjectToID(hypLengthFromEdges), "LengthFromEdges") -idarea = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypArea) ) -smeshgui.SetName(idarea, "MaxElementArea") print "-------------------------- MaxElementVolume" -maxElementVolume = 150 +maxElementVolume = 1000 -hypothesis=gen.CreateHypothesis("MaxElementVolume") -hypVolume=hypothesis._narrow(SMESH.SMESH_MaxElementVolume) +hypVolume=smesh.CreateHypothesis("MaxElementVolume", "libStdMeshersEngine.so") hypVolume.SetMaxElementVolume(maxElementVolume) + print hypVolume.GetName() print hypVolume.GetId() print hypVolume.GetMaxElementVolume() -idvolume = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypVolume) ) -smeshgui.SetName(idvolume, "MaxElementVolume") +smeshgui.SetName(salome.ObjectToID(hypVolume), "MaxElementVolume_1000") # ---- create Algorithms @@ -90,66 +85,56 @@ print "-------------------------- create Algorithms" print "-------------------------- Regular_1D" -hypothesis=gen.CreateHypothesis("Regular_1D") -regular1D = hypothesis._narrow(SMESH.SMESH_Regular_1D) -regularID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(regular1D) ) -smeshgui.SetName(regularID, "Wire Discretisation") +regular1D=smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so") + +smeshgui.SetName(salome.ObjectToID(regular1D), "Wire Discretisation") print "-------------------------- MEFISTO_2D" -hypothesis=gen.CreateHypothesis("MEFISTO_2D") -mefisto2D = hypothesis._narrow(SMESH.SMESH_MEFISTO_2D) -mefistoID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(mefisto2D) ) -smeshgui.SetName(mefistoID, "MEFISTO_2D") +mefisto2D=smesh.CreateHypothesis("MEFISTO_2D", "libStdMeshersEngine.so") + +smeshgui.SetName(salome.ObjectToID(mefisto2D), "MEFISTO_2D") print "-------------------------- NETGEN_3D" -hypothesis=gen.CreateHypothesis("NETGEN_3D") -netgen3D = hypothesis._narrow(SMESH.SMESH_NETGEN_3D) -netgenID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(netgen3D) ) -smeshgui.SetName(netgenID, "NETGEN_3D") +netgen3D=smesh.CreateHypothesis("NETGEN_3D", "libNETGENEngine.so") + +smeshgui.SetName(salome.ObjectToID(netgen3D), "NETGEN_3D") # ---- init a Mesh with the compshell -mesh=gen.Init(idcomp) -idmesh = smeshgui.AddNewMesh( salome.orb.object_to_string(mesh) ) -smeshgui.SetName(idmesh, "MeshcompShell") -smeshgui.SetShape(idcomp, idmesh) +mesh=smesh.CreateMesh(compshell) +smeshgui.SetName(salome.ObjectToID(mesh), "MeshcompShel") # ---- add hypothesis to compshell print "-------------------------- add hypothesis to compshell" -ret=mesh.AddHypothesis(compshell,regular1D) -print ret -ret=mesh.AddHypothesis(compshell,hypNbSeg) -print ret -ret=mesh.AddHypothesis(compshell,mefisto2D) -print ret -ret=mesh.AddHypothesis(compshell,hypArea) -print ret -ret=mesh.AddHypothesis(compshell,netgen3D) -print ret -ret=mesh.AddHypothesis(compshell,hypVolume) -print ret +mesh.AddHypothesis(compshell,regular1D) +mesh.AddHypothesis(compshell,hypNbSeg) + +mesh.AddHypothesis(compshell,mefisto2D) +mesh.AddHypothesis(compshell,hypLengthFromEdges) -smeshgui.SetAlgorithms( idmesh, regularID) -smeshgui.SetHypothesis( idmesh, idseg ) -smeshgui.SetAlgorithms( idmesh, mefistoID ) -smeshgui.SetHypothesis( idmesh, idarea ) -smeshgui.SetAlgorithms( idmesh, netgenID ) -smeshgui.SetHypothesis( idmesh, idvolume ) +mesh.AddHypothesis(compshell,netgen3D) +mesh.AddHypothesis(compshell,hypVolume) -sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(1) print "-------------------------- compute compshell" -ret=gen.Compute(mesh,idcomp) +ret=smesh.Compute(mesh,compshell) print ret if ret != 0: log=mesh.GetLog(0) # no erase trace for linelog in log: print linelog + print "Information about the MeshcompShel:" + print "Number of nodes : ", mesh.NbNodes() + print "Number of edges : ", mesh.NbEdges() + print "Number of faces : ", mesh.NbFaces() + print "Number of triangles : ", mesh.NbTriangles() + print "Number of volumes : ", mesh.NbVolumes() + print "Number of tetrahedrons : ", mesh.NbTetras() + else: print "problem when computing the mesh" - -sg.updateObjBrowser(1) diff --git a/src/SMESH_SWIG/SMESH_flight_skin.py b/src/SMESH_SWIG/SMESH_flight_skin.py index b352355b8..6165621b9 100644 --- a/src/SMESH_SWIG/SMESH_flight_skin.py +++ b/src/SMESH_SWIG/SMESH_flight_skin.py @@ -4,23 +4,25 @@ # Hypothesis and algorithms for the mesh generation are global # +import os import salome -from salome import sg - import geompy -import SMESH -import smeshpy +import StdMeshers + +geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM") +smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH") + +smeshgui = salome.ImportComponentGUI("SMESH") +smeshgui.Init(salome.myStudyId); + -geom = geompy.geom -myBuilder = geompy.myBuilder +# ---------------------------- GEOM -------------------------------------- ShapeTypeShell = 3 ShapeTypeFace = 4 ShapeTypeEdge = 6 -import os - # import a BRep #before running this script, please be sure about #the path the file fileName @@ -43,12 +45,8 @@ print "number of Shells in flight : ",len(subShellList) print "number of Faces in flight : ",len(subFaceList) print "number of Edges in flight : ",len(subEdgeList) -# ---- launch SMESH - -smeshgui = salome.ImportComponentGUI("SMESH") -smeshgui.Init(salome.myStudyId) -gen=smeshpy.smeshpy() +### ---------------------------- SMESH -------------------------------------- # ---- create Hypothesis @@ -58,27 +56,23 @@ print "-------------------------- LocalLength" lengthOfSegments = 0.3 -hypothesis=gen.CreateHypothesis("LocalLength") -hypLength=hypothesis._narrow(SMESH.SMESH_LocalLength) +hypLength=smesh.CreateHypothesis("LocalLength", "libStdMeshersEngine.so") hypLength.SetLength(lengthOfSegments) -hypLengthID = hypLength.GetId() + print hypLength.GetName() -print hypLengthID +print hypLength.GetId() print hypLength.GetLength() -idlen = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypLength) ) -smeshgui.SetName(idlen, "LocalLength") +smeshgui.SetName(salome.ObjectToID(hypLength), "LocalLength_0.3") print "-------------------------- LengthFromEdges" -hypothesis=gen.CreateHypothesis("LengthFromEdges") -hypLengthFromEdge=hypothesis._narrow(SMESH.SMESH_LengthFromEdges) -hypLengthFromEdgeID = hypLengthFromEdge.GetId() +hypLengthFromEdge=smesh.CreateHypothesis("LengthFromEdges", "libStdMeshersEngine.so") + print hypLengthFromEdge.GetName() -print hypLengthFromEdgeID +print hypLengthFromEdge.GetId() -idlenfromedge = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypLengthFromEdge) ) -smeshgui.SetName(idlenfromedge, "LengthFromEdge") +smeshgui.SetName(salome.ObjectToID(hypLengthFromEdge), "LengthFromEdge") # ---- create Algorithms @@ -86,54 +80,46 @@ print "-------------------------- create Algorithms" print "-------------------------- Regular_1D" -hypothesis=gen.CreateHypothesis("Regular_1D") -regular1D = hypothesis._narrow(SMESH.SMESH_Regular_1D) -regularID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(regular1D) ) -smeshgui.SetName(regularID, "Wire Discretisation") +regular1D=smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so") + +smeshgui.SetName(salome.ObjectToID(regular1D), "Wire Discretisation") print "-------------------------- MEFISTO_2D" -hypothesis=gen.CreateHypothesis("MEFISTO_2D") -mefisto2D = hypothesis._narrow(SMESH.SMESH_MEFISTO_2D) -mefistoID = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(mefisto2D) ) -smeshgui.SetName(mefistoID, "MEFISTO_2D") +mefisto2D=smesh.CreateHypothesis("MEFISTO_2D", "libStdMeshersEngine.so") + +smeshgui.SetName(salome.ObjectToID(mefisto2D), "MEFISTO_2D") # ---- init a Mesh with the shell +shape_mesh = salome.IDToObject( idShape ) -mesh=gen.Init(idShape) -idmesh = smeshgui.AddNewMesh( salome.orb.object_to_string(mesh) ) -smeshgui.SetName(idmesh, "MeshFlight") -smeshgui.SetShape(idShape, idmesh) +mesh=smesh.CreateMesh(shape_mesh) +smeshgui.SetName(salome.ObjectToID(mesh), "MeshFlight") # ---- add hypothesis to flight print "-------------------------- add hypothesis to flight" -ret=mesh.AddHypothesis(shape,regular1D) -print ret -ret=mesh.AddHypothesis(shape,hypLength) -print ret -ret=mesh.AddHypothesis(shape,mefisto2D) -print ret -ret=mesh.AddHypothesis(shape,hypLengthFromEdge) -print ret - -smeshgui.SetAlgorithms( idmesh, regularID) -smeshgui.SetHypothesis( idmesh, idlen ) -smeshgui.SetAlgorithms( idmesh, mefistoID ) -smeshgui.SetHypothesis( idmesh, idlenfromedge) +mesh.AddHypothesis(shape_mesh,regular1D) +mesh.AddHypothesis(shape_mesh,hypLength) +mesh.AddHypothesis(shape_mesh,mefisto2D) +mesh.AddHypothesis(shape_mesh,hypLengthFromEdge) -sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(1) print "-------------------------- compute the skin flight" -ret=gen.Compute(mesh,idShape) +ret=smesh.Compute(mesh,shape_mesh) print ret if ret != 0: log=mesh.GetLog(0) # no erase trace for linelog in log: print linelog + print "Information about the Mesh_mechanic_tetra:" + print "Number of nodes : ", mesh.NbNodes() + print "Number of edges : ", mesh.NbEdges() + print "Number of faces : ", mesh.NbFaces() + print "Number of triangles : ", mesh.NbTriangles() + print "Number of volumes : ", mesh.NbVolumes() else: print "probleme when computing the mesh" - -sg.updateObjBrowser(1) diff --git a/src/SMESH_SWIG/SMESH_freebord.py b/src/SMESH_SWIG/SMESH_freebord.py new file mode 100644 index 000000000..d24e34070 --- /dev/null +++ b/src/SMESH_SWIG/SMESH_freebord.py @@ -0,0 +1,78 @@ +import salome +from geompy import gg +import geompy +import SMESH + +import StdMeshers + +ShapeTypeCompSolid = 1 +ShapeTypeSolid = 2 +ShapeTypeShell = 3 +ShapeTypeFace = 4 +ShapeTypeWire = 5 +ShapeTypeEdge = 6 +ShapeTypeVertex = 7 + +geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM") +smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH") + +geom.GetCurrentStudy(salome.myStudy._get_StudyId()) +smesh.SetCurrentStudy(salome.myStudy) + +# Create box without one plane + +box = geompy.MakeBox(0., 0., 0., 10., 20., 30.) +subShapeList = geompy.SubShapeAll(box,ShapeTypeFace) + +FaceList = [] +for i in range( 5 ): + FaceList.append( subShapeList[ i ]._get_Name() ) + +aBox = geompy.MakeSewing( FaceList, 1. ) +idbox = geompy.addToStudy( aBox, "box" ) + +aBox = salome.IDToObject( idbox ) + +# Create mesh + +hyp1 = smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so") +hyp1.SetNumberOfSegments(5) +hyp2 = smesh.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so") +hyp2.SetMaxElementArea(20) +hyp3 = smesh.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so") +hyp3.SetMaxElementArea(50) + +algo1 = smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so") +algo2 = smesh.CreateHypothesis("MEFISTO_2D", "libStdMeshersEngine.so") + +mesh = smesh.CreateMesh(aBox) +mesh.AddHypothesis(aBox,hyp1) +mesh.AddHypothesis(aBox,hyp2) +mesh.AddHypothesis(aBox,algo1) +mesh.AddHypothesis(aBox,algo2) + +smesh.Compute(mesh,aBox) + +smeshgui = salome.ImportComponentGUI("SMESH") +smeshgui.Init(salome.myStudyId); +smeshgui.SetName( salome.ObjectToID( mesh ), "Mesh_freebord" ); + +# Criterion : Free edges +aFilterMgr = smesh.CreateFilterManager() +aPredicate = aFilterMgr.CreateFreeBorders() +aFilter = aFilterMgr.CreateFilter() +aFilter.SetPredicate( aPredicate ) + +anIds = aFilter.GetElementsId( mesh ) + +# print result +print "Criterion: Free edges Nb = ", len( anIds ) +for i in range( len( anIds ) ): + print anIds[ i ] + +# create group +aGroup = mesh.CreateGroup( SMESH.EDGE, "Free edges" ) +aGroup.Add( anIds ) + + +salome.sg.updateObjBrowser(1) diff --git a/src/SMESH_SWIG/SMESH_mechanic.py b/src/SMESH_SWIG/SMESH_mechanic.py index 8a0a3a339..3011c0c82 100644 --- a/src/SMESH_SWIG/SMESH_mechanic.py +++ b/src/SMESH_SWIG/SMESH_mechanic.py @@ -24,25 +24,21 @@ # Module : SMESH # $Header$ -import SMESH -import smeshpy import salome -from salome import sg -import math -#import SMESH_BasicHypothesis_idl - import geompy +geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM") +smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH") - -# ---------------------------- GEOM -------------------------------------- -geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM") -myBuilder = salome.myStudy.NewBuilder() -#from geompy import gg +geom.GetCurrentStudy(salome.myStudy._get_StudyId()) +smesh.SetCurrentStudy(salome.myStudy) smeshgui = salome.ImportComponentGUI("SMESH") smeshgui.Init(salome.myStudyId); +import StdMeshers + +# ---------------------------- GEOM -------------------------------------- ShapeTypeCompSolid = 1 ShapeTypeSolid = 2 ShapeTypeShell = 3 @@ -51,9 +47,7 @@ ShapeTypeWire = 5 ShapeTypeEdge = 6 ShapeTypeVertex = 7 - # ---- define contigous arcs and segment to define a closed wire - p1 = geom.MakePointStruct( 100.0, 0.0, 0.0 ) p2 = geom.MakePointStruct( 50.0, 50.0, 0.0 ) p3 = geom.MakePointStruct( 100.0, 100.0, 0.0 ) @@ -69,9 +63,7 @@ arc2 = geom.MakeArc( p4, p5, p6 ) p7 = geom.MakePointStruct( 120.0, 30.0, 0.0 ) arc3 = geom.MakeArc( p6, p7, p1 ) - # ---- define a closed wire with arcs and segment - List1 = [] List1.append( arc1 ) List1.append( seg1 ) @@ -85,13 +77,11 @@ wire1 = geom.MakeWire( ListIOR1 ) Id_wire1 = geompy.addToStudy( wire1, "wire1") - # ---- define a planar face with wire WantPlanarFace = 1 #True face1 = geom.MakeFace( wire1, WantPlanarFace ) Id_face1 = geompy.addToStudy( face1, "face1") - # ---- create a shape by extrusion pO = geom.MakePointStruct( 0.0, 0.0, 0.0 ) pz = geom.MakePointStruct( 0.0, 0.0, 100.0 ) @@ -99,8 +89,6 @@ pz = geom.MakePointStruct( 0.0, 0.0, 100.0 ) prism1 = geom.MakePrism( face1, pO, pz ) Id_prism1 = geompy.addToStudy( prism1, "prism1") - - # ---- create two cylinders pc1 = geom.MakePointStruct( 90.0, 50.0, -40.0 ) @@ -114,7 +102,6 @@ cyl2 = geom.MakeCylinder( pc2, vz, radius, height ) Id_Cyl1 = geompy.addToStudy( cyl1, "cyl1" ) Id_Cyl2 = geompy.addToStudy( cyl2, "cyl2" ) - # ---- cut with cyl1 shape = geom.MakeBoolean( prism1, cyl1, 2 ) @@ -123,203 +110,185 @@ shape1 = geom.MakeBoolean( shape, cyl2, 3 ) Id_shape1 = geompy.addToStudy( shape1, "shape1") - +#faces = geompy.SubShapeAllSorted( shape1, ShapeTypeFace) +#i = 0 +#for face in faces: +# geompy.addToStudy(face,"face_" + str(i)) +# i = i+1 + # ---- add a face sub shape in study to be meshed different IdSubFaceList = [] -IdSubFaceList.append(10) +IdSubFaceList.append(1) sub_face = geompy.SubShapeSorted( shape1, ShapeTypeFace, IdSubFaceList ) name = geompy.SubShapeName( sub_face._get_Name(), shape1._get_Name() ) Id_SubFace = geompy.addToStudyInFather( shape1, sub_face, name ) - # ---- add a face sub shape in study to be meshed different IdSubFaceL = [] -IdSubFaceL.append(7) +IdSubFaceL.append(2) sub_face2 = geompy.SubShapeSorted( shape1, ShapeTypeFace, IdSubFaceL ) name = geompy.SubShapeName( sub_face2._get_Name(), shape1._get_Name() ) Id_SubFace2 = geompy.addToStudyInFather( shape1, sub_face2, name ) +# ---- add a face sub shape in study to be meshed different +IdSubFaceL = [] +IdSubFaceL.append(3) +sub_face3 = geompy.SubShapeSorted( shape1, ShapeTypeFace, IdSubFaceL ) +name = geompy.SubShapeName( sub_face3._get_Name(), shape1._get_Name() ) +Id_SubFace3 = geompy.addToStudyInFather( shape1, sub_face3, name ) +# ---- add a face sub shape in study to be meshed different +IdSubFaceL = [] +IdSubFaceL.append(6) +sub_face4 = geompy.SubShapeSorted( shape1, ShapeTypeFace, IdSubFaceL ) +name = geompy.SubShapeName( sub_face4._get_Name(), shape1._get_Name() ) -# ---------------------------- SMESH -------------------------------------- - -# ---- launch SMESH, init a Mesh with shape 'shape1' -gen = smeshpy.smeshpy() -mesh = gen.Init( Id_shape1 ) +Id_SubFace4 = geompy.addToStudyInFather( shape1, sub_face4, name ) -idmesh = smeshgui.AddNewMesh( salome.orb.object_to_string(mesh) ) -smeshgui.SetName( idmesh, "Mesh_meca" ); -smeshgui.SetShape( Id_shape1, idmesh ); +# ---------------------------- SMESH -------------------------------------- # ------------------------------ Length Hypothesis print "-------------------------- create Hypothesis" print "-------------------------- LocalLength" -hyp1 = gen.CreateHypothesis( "LocalLength" ) -hypLen1 = hyp1._narrow( SMESH.SMESH_LocalLength ) -hypLen1.SetLength( 100.0 ) -print hypLen1.GetName() -print hypLen1.GetId() -print hypLen1.GetLength() - -idlength = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypLen1) ); -smeshgui.SetName(idlength, "Local_Length_100"); +hyp1 = smesh.CreateHypothesis("LocalLength", "libStdMeshersEngine.so") +hyp1.SetLength( 100.0 ) +print hyp1.GetName() +print hyp1.GetId() +print hyp1.GetLength() +idlength = salome.ObjectToID(hyp1) +smeshgui.SetName(idlength, "Local_Length_100"); print "-------------------------- NumberOfSegments" -hyp2 = gen.CreateHypothesis( "NumberOfSegments" ) -hypNbSeg1 = hyp2._narrow( SMESH.SMESH_NumberOfSegments ) -hypNbSeg1.SetNumberOfSegments( 10 ) -print hypNbSeg1.GetName() -print hypNbSeg1.GetId() -print hypNbSeg1.GetNumberOfSegments() +hyp2 = smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so") +hyp2.SetNumberOfSegments( 10 ) +print hyp2.GetName() +print hyp2.GetId() +print hyp2.GetNumberOfSegments() -idseg = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypNbSeg1) ); +idseg = salome.ObjectToID(hyp2) smeshgui.SetName(idseg, "NumberOfSegments_12"); - print "-------------------------- MaxElementArea" -hyp3 = gen.CreateHypothesis( "MaxElementArea" ) -hypArea1 = hyp3._narrow( SMESH.SMESH_MaxElementArea ) -hypArea1.SetMaxElementArea( 25 ) -print hypArea1.GetName() -print hypArea1.GetId() -print hypArea1.GetMaxElementArea() +hyp3 = smesh.CreateHypothesis( "MaxElementArea", "libStdMeshersEngine.so" ) +hyp3.SetMaxElementArea( 25 ) +print hyp3.GetName() +print hyp3.GetId() +print hyp3.GetMaxElementArea() -idarea1 = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypArea1) ); +idarea1 = salome.ObjectToID(hyp3) smeshgui.SetName(idarea1, "MaxElementArea_20"); - - print "-------------------------- MaxElementArea" -hyp4 = gen.CreateHypothesis( "MaxElementArea" ) -hypArea2 = hyp4._narrow( SMESH.SMESH_MaxElementArea ) -hypArea2.SetMaxElementArea( 35 ) -print hypArea2. GetName() -print hypArea2.GetId() -print hypArea2.GetMaxElementArea() +hyp4 = smesh.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so") +hyp4.SetMaxElementArea( 35 ) +print hyp4.GetName() +print hyp4.GetId() +print hyp4.GetMaxElementArea() -idarea2 = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypArea2) ); +idarea2 = salome.ObjectToID(hyp4) smeshgui.SetName(idarea2, "MaxElementArea_30"); print "-------------------------- Regular_1D" -alg1 = gen.CreateHypothesis( "Regular_1D" ) -algo1 = alg1._narrow( SMESH.SMESH_Algo ) -listHyp =algo1.GetCompatibleHypothesis() +alg1 = smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so") +listHyp =alg1.GetCompatibleHypothesis() for hyp in listHyp: print hyp -algoReg1d = alg1._narrow( SMESH.SMESH_Regular_1D ) -print algoReg1d.GetName() -print algoReg1d.GetId() +print alg1.GetName() +print alg1.GetId() -idreg1d = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(algoReg1d) ); +idreg1d = salome.ObjectToID(alg1) smeshgui.SetName( idreg1d, "Regular_1D" ); - - print "-------------------------- MEFISTO_2D" -alg2 = gen.CreateHypothesis( "MEFISTO_2D" ) -algo2 = alg2._narrow( SMESH.SMESH_Algo ) -listHyp = algo2.GetCompatibleHypothesis() +alg2 = smesh.CreateHypothesis("MEFISTO_2D", "libStdMeshersEngine.so") +listHyp = alg2.GetCompatibleHypothesis() for hyp in listHyp: print hyp -algoMef = alg2._narrow( SMESH.SMESH_MEFISTO_2D ) -print algoMef.GetName() -print algoMef.GetId() +print alg2.GetName() +print alg2.GetId() -idmef = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(algoMef) ); +idmef = salome.ObjectToID(alg2) smeshgui.SetName( idmef, "MEFISTO_2D" ); - - print "-------------------------- SMESH_Quadrangle_2D" -alg3 = gen.CreateHypothesis( "Quadrangle_2D" ) -algo3 = alg3._narrow( SMESH.SMESH_2D_Algo ) -listHyp = algo3.GetCompatibleHypothesis() +alg3 = smesh.CreateHypothesis( "Quadrangle_2D", "libStdMeshersEngine.so" ) +listHyp = alg3.GetCompatibleHypothesis() for hyp in listHyp: print hyp -algoQad2 = alg3._narrow( SMESH.SMESH_Quadrangle_2D ) -print algoQad2.GetName() -print algoQad2.GetId() +print alg3.GetName() +print alg3.GetId() -idqad2 = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(algoQad2) ); +idqad2 = salome.ObjectToID(alg3) smeshgui.SetName( idqad2, "SMESH_Quadrangle_2D" ); - print "-------------------------- add hypothesis to main shape1" shape_mesh = salome.IDToObject( Id_shape1 ) -submesh = mesh.GetElementsOnShape( shape_mesh ) - -ret = mesh.AddHypothesis( shape_mesh, algoReg1d ) # Regular 1D/wire discretisation -print ret -ret = mesh.AddHypothesis( shape_mesh, algoMef ) # MEFISTO 2D -print ret -ret = mesh.AddHypothesis( shape_mesh, hypNbSeg1 ) # nb segments -print ret -ret = mesh.AddHypothesis( shape_mesh, hypArea1 ) # max area -print ret -smeshgui.SetAlgorithms( idmesh, idreg1d ); # Regular 1D/wire discretisation -smeshgui.SetAlgorithms( idmesh, idmef ); # MEFISTO 2D -smeshgui.SetHypothesis( idmesh, idseg ); # nb segments -smeshgui.SetHypothesis( idmesh, idarea1 ); # max area +mesh = smesh.CreateMesh(shape_mesh) +idmesh = salome.ObjectToID(mesh) +smeshgui.SetName( idmesh, "Mesh_mechanic" ); +mesh.AddHypothesis( shape_mesh, alg1 ) # Regular 1D/wire discretisation +mesh.AddHypothesis( shape_mesh, alg2 ) # MEFISTO 2D -print "-------------------------- add hypothesis and algorith to sub face" +ret = mesh.AddHypothesis( shape_mesh, hyp2 ) # nb segments +ret = mesh.AddHypothesis( shape_mesh, hyp3 ) # max area -sub_face = salome.IDToObject( Id_SubFace ) -submesh = mesh.GetElementsOnShape( sub_face ) +print "--------Add hypothesis and algorith to sub face" -ret = mesh.AddHypothesis( sub_face, algoQad2 ) # Quadrangle 2D -print ret -ret = mesh.AddHypothesis( sub_face, hypArea2 ) # max area -print ret +#sub_face = salome.IDToObject( Id_SubFace ) +submesh = mesh.GetSubMesh(sub_face, "SubMeshFace") -idsm2 = smeshgui.AddSubMeshOnShape( idmesh, - Id_SubFace, - salome.orb.object_to_string(submesh), - ShapeTypeFace ) +mesh.AddHypothesis( sub_face, alg3 ) # Quadrangle 2D +mesh.AddHypothesis( sub_face, hyp4 ) # max area -smeshgui.SetName(idsm2, "SubMeshFace") -smeshgui.SetAlgorithms( idsm2, idqad2 ); # Quadrangle 2D -smeshgui.SetHypothesis( idsm2, idarea2 ); # max area +print "--------Add hypothesis and algorith to sub face 2" +#sub_face2 = salome.IDToObject( Id_SubFace2 ) +submesh = mesh.GetSubMesh(sub_face2, "SubMeshFace2") +mesh.AddHypothesis( sub_face2, alg3 ) # Quadrangle 2D +ret = mesh.AddHypothesis( sub_face2, hyp4 ) # max area -print "-------------------------- add hypothesis and algorith to sub face" +print "--------Add hypothesis and algorith to sub face 3" -sub_face2 = salome.IDToObject( Id_SubFace2 ) -submesh = mesh.GetElementsOnShape( sub_face2 ) +#sub_face3 = salome.IDToObject( Id_SubFace3 ) +submesh = mesh.GetSubMesh(sub_face3, "SubMeshFace3") -ret = mesh.AddHypothesis( sub_face2, algoQad2 ) # Quadrangle 2D -print ret -ret = mesh.AddHypothesis( sub_face2, hypArea2 ) # max area -print ret +mesh.AddHypothesis( sub_face3, alg3 ) # Quadrangle 2D +ret = mesh.AddHypothesis( sub_face3, hyp4 ) # max area -idsm3 = smeshgui.AddSubMeshOnShape( idmesh, - Id_SubFace2, - salome.orb.object_to_string(submesh), - ShapeTypeFace ) +print "--------Add hypothesis and algorith to sub face 4" -smeshgui.SetName(idsm3, "SubMeshFace2") -smeshgui.SetAlgorithms( idsm3, idqad2 ); # Quadrangle 2D -smeshgui.SetHypothesis( idsm3, idarea2 ); # max area +#sub_face4 = salome.IDToObject( Id_SubFace4 ) +submesh = mesh.GetSubMesh(sub_face4, "SubMeshFace4") +mesh.AddHypothesis( sub_face4, alg3 ) # Quadrangle 2D +ret = mesh.AddHypothesis( sub_face4, hyp4 ) # max area +smesh.Compute(mesh,shape_mesh) +print "Information about the Mesh_mechanic:" +print "Number of nodes : ", mesh.NbNodes() +print "Number of edges : ", mesh.NbEdges() +print "Number of faces : ", mesh.NbFaces() +print "Number of triangles : ", mesh.NbTriangles() +print "Number of quadrangles: ", mesh.NbQuadrangles() -sg.updateObjBrowser(1); +salome.sg.updateObjBrowser(1); diff --git a/src/SMESH_SWIG/SMESH_mechanic_tetra.py b/src/SMESH_SWIG/SMESH_mechanic_tetra.py index 2446828a9..689614891 100644 --- a/src/SMESH_SWIG/SMESH_mechanic_tetra.py +++ b/src/SMESH_SWIG/SMESH_mechanic_tetra.py @@ -24,22 +24,19 @@ # Module : SMESH # $Header$ -import SMESH -import smeshpy import salome -from salome import sg -import math - import geompy -# ---------------------------- GEOM -------------------------------------- -geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM") -myBuilder = salome.myStudy.NewBuilder() -#from geompy import gg +import StdMeshers +import NETGENPlugin + +geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM") +smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH") smeshgui = salome.ImportComponentGUI("SMESH") -smeshgui.Init(salome.myStudyId) +smeshgui.Init(salome.myStudyId); +# ---------------------------- GEOM -------------------------------------- ShapeTypeCompSolid = 1 ShapeTypeSolid = 2 ShapeTypeShell = 3 @@ -124,131 +121,100 @@ print "number of Edges in mechanic : ",len(subEdgeList) ### ---------------------------- SMESH -------------------------------------- -# ---- launch SMESH, init a Mesh with shape 'mechanic' - -gen = smeshpy.smeshpy() -mesh = gen.Init( idMechanic ) - -idmesh = smeshgui.AddNewMesh( salome.orb.object_to_string(mesh) ) -smeshgui.SetName( idmesh, "Mesh_mechanic" ) -smeshgui.SetShape( idMechanic, idmesh ) - print "-------------------------- NumberOfSegments" numberOfSegment = 10 -hypNumberOfSegment = gen.CreateHypothesis( "NumberOfSegments" ) -hypNbSeg = hypNumberOfSegment._narrow( SMESH.SMESH_NumberOfSegments ) +hypNbSeg = smesh.CreateHypothesis( "NumberOfSegments", "libStdMeshersEngine.so" ) hypNbSeg.SetNumberOfSegments(numberOfSegment) print hypNbSeg.GetName() print hypNbSeg.GetId() print hypNbSeg.GetNumberOfSegments() -idSeg = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypNbSeg) ) -smeshgui.SetName(idSeg, "NumberOfSegments") +smeshgui.SetName(salome.ObjectToID(hypNbSeg), "NumberOfSegments_10") print "-------------------------- MaxElementArea" maxElementArea = 20 -hypMaxElementArea = gen.CreateHypothesis( "MaxElementArea" ) -hypArea = hypMaxElementArea._narrow( SMESH.SMESH_MaxElementArea ) +hypArea = smesh.CreateHypothesis( "MaxElementArea", "libStdMeshersEngine.so" ) hypArea.SetMaxElementArea(maxElementArea) print hypArea.GetName() print hypArea.GetId() print hypArea.GetMaxElementArea() -idArea = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypArea) ) -smeshgui.SetName(idArea, "MaxElementArea") +smeshgui.SetName(salome.ObjectToID(hypArea), "MaxElementArea_20") print "-------------------------- MaxElementVolume" maxElementVolume = 20 -hypMaxElementVolume = gen.CreateHypothesis( "MaxElementVolume" ) -hypVolume = hypMaxElementVolume._narrow( SMESH.SMESH_MaxElementVolume ) +hypVolume = smesh.CreateHypothesis( "MaxElementVolume", "libStdMeshersEngine.so" ) hypVolume.SetMaxElementVolume(maxElementVolume) print hypVolume.GetName() print hypVolume.GetId() print hypVolume.GetMaxElementVolume() -idVolume = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypVolume) ) -smeshgui.SetName(idVolume, "MaxElementArea") +smeshgui.SetName(salome.ObjectToID(hypVolume), "MaxElementVolume_20") print "-------------------------- Regular_1D" -alg1D = gen.CreateHypothesis( "Regular_1D" ) -algo1D = alg1D._narrow( SMESH.SMESH_Algo ) -listHyp =algo1D.GetCompatibleHypothesis() +algoReg1D = smesh.CreateHypothesis( "Regular_1D", "libStdMeshersEngine.so" ) +listHyp =algoReg1D.GetCompatibleHypothesis() for hyp in listHyp: print hyp -algoReg1D = alg1D._narrow( SMESH.SMESH_Regular_1D ) print algoReg1D.GetName() print algoReg1D.GetId() -idReg1D = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(algoReg1D) ) -smeshgui.SetName( idReg1D, "Regular_1D" ) +smeshgui.SetName(salome.ObjectToID(algoReg1D), "Regular_1D" ) print "-------------------------- MEFISTO_2D" -alg2D = gen.CreateHypothesis( "MEFISTO_2D" ) -algo2D = alg2D._narrow( SMESH.SMESH_Algo ) -listHyp = algo2D.GetCompatibleHypothesis() +algoMef = smesh.CreateHypothesis( "MEFISTO_2D", "libStdMeshersEngine.so" ) +listHyp = algoMef.GetCompatibleHypothesis() for hyp in listHyp: print hyp -algoMef = alg2D._narrow( SMESH.SMESH_MEFISTO_2D ) print algoMef.GetName() print algoMef.GetId() -idMef = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(algoMef) ) -smeshgui.SetName( idMef, "MEFISTO_2D" ) +smeshgui.SetName(salome.ObjectToID(algoMef), "MEFISTO_2D" ) print "-------------------------- NETGEN_3D" -alg3D = gen.CreateHypothesis( "NETGEN_3D" ) -algo3D = alg3D._narrow( SMESH.SMESH_Algo ) -listHyp = algo3D.GetCompatibleHypothesis() +algoNg = smesh.CreateHypothesis( "NETGEN_3D", "libNETGENEngine.so" ) +listHyp = algoNg.GetCompatibleHypothesis() for hyp in listHyp: print hyp -algoNg = alg3D._narrow( SMESH.SMESH_NETGEN_3D ) print algoNg.GetName() print algoNg.GetId() -idNg = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(algoNg) ) -smeshgui.SetName( idNg, "NETGEN_2D" ) +smeshgui.SetName(salome.ObjectToID(algoNg), "NETGEN_3D" ) print "-------------------------- add hypothesis to main mechanic" shape_mesh = salome.IDToObject( idMechanic ) -submesh = mesh.GetElementsOnShape( shape_mesh ) - -ret = mesh.AddHypothesis( shape_mesh, algoReg1D ) # Regular 1D/wire discretisation -print ret -ret = mesh.AddHypothesis( shape_mesh, algoMef ) # MEFISTO 2D -print ret -ret = mesh.AddHypothesis( shape_mesh, algoNg ) # NETGEN 3D -print ret -ret = mesh.AddHypothesis( shape_mesh, hypNbSeg ) # nb segments -print ret -ret = mesh.AddHypothesis( shape_mesh, hypArea ) # max area -print ret -ret = mesh.AddHypothesis( shape_mesh, hypVolume ) # max volume -print ret - -smeshgui.SetAlgorithms( idmesh, idReg1D ); # Regular 1D/wire discretisation -smeshgui.SetAlgorithms( idmesh, idMef ); # MEFISTO 2D -smeshgui.SetAlgorithms( idmesh, idNg ); # NETGEN 3D -smeshgui.SetHypothesis( idmesh, idSeg ); # nb segments -smeshgui.SetHypothesis( idmesh, idArea ); # max area -smeshgui.SetHypothesis( idmesh, idVolume ); # max volume - -sg.updateObjBrowser(1); + +mesh = smesh.CreateMesh(shape_mesh) +smeshgui.SetName(salome.ObjectToID(mesh), "Mesh_mechanic_tetra" ); + +mesh.AddHypothesis( shape_mesh, algoReg1D ) # Regular 1D/wire discretisation +mesh.AddHypothesis( shape_mesh, algoMef ) # MEFISTO 2D +mesh.AddHypothesis( shape_mesh, algoNg ) # NETGEN 3D + +mesh.AddHypothesis( shape_mesh, hypNbSeg ) # nb segments +mesh.AddHypothesis( shape_mesh, hypArea ) # max area +mesh.AddHypothesis( shape_mesh, hypVolume ) # max volume print "-------------------------- compute the mesh of the mechanic piece" -ret=gen.Compute(mesh,idMechanic) -print ret -log=mesh.GetLog(0) # no erase trace -for linelog in log: - print linelog +smesh.Compute(mesh,shape_mesh) + +print "Information about the Mesh_mechanic_tetra:" +print "Number of nodes : ", mesh.NbNodes() +print "Number of edges : ", mesh.NbEdges() +print "Number of faces : ", mesh.NbFaces() +print "Number of triangles : ", mesh.NbTriangles() +print "Number of volumes: ", mesh.NbVolumes() +print "Number of tetrahedrons: ", mesh.NbTetras() + +salome.sg.updateObjBrowser(1); -sg.updateObjBrowser(1) diff --git a/src/SMESH_SWIG/SMESH_test0.py b/src/SMESH_SWIG/SMESH_test0.py index bce99c6e9..ce717fdde 100644 --- a/src/SMESH_SWIG/SMESH_test0.py +++ b/src/SMESH_SWIG/SMESH_test0.py @@ -35,9 +35,6 @@ geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM") myBuilder = salome.myStudy.NewBuilder() from geompy import gg -smeshgui = salome.ImportComponentGUI("SMESH") -smeshgui.Init(salome.myStudyId); - ShapeTypeCompSolid = 1 ShapeTypeSolid = 2 ShapeTypeShell = 3 diff --git a/src/SMESH_SWIG/SMESH_test1.py b/src/SMESH_SWIG/SMESH_test1.py index 35a3ef00b..a16b63d5a 100644 --- a/src/SMESH_SWIG/SMESH_test1.py +++ b/src/SMESH_SWIG/SMESH_test1.py @@ -22,21 +22,16 @@ # File : SMESH_test1.py # Module : SMESH -import SMESH -import smeshpy import salome -from salome import sg -import math -#import SMESH_BasicHypothesis_idl - import geompy -geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM") -myBuilder = salome.myStudy.NewBuilder() -from geompy import gg +import StdMeshers -smeshgui = salome.ImportComponentGUI("SMESH") -smeshgui.Init(salome.myStudyId); +geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM") +smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH") + +geom.GetCurrentStudy(salome.myStudy._get_StudyId()) +smesh.SetCurrentStudy(salome.myStudy) ShapeTypeCompSolid = 1 ShapeTypeSolid = 2 @@ -75,135 +70,102 @@ name = geompy.SubShapeName( edge._get_Name(), face._get_Name() ) print name idedge=geompy.addToStudyInFather(face,edge,name) -# ---- launch SMESH, init a Mesh with the box -gen=smeshpy.smeshpy() -mesh=gen.Init(idbox) - -idmesh = smeshgui.AddNewMesh( salome.orb.object_to_string(mesh) ) -smeshgui.SetName(idmesh, "Meshbox"); -smeshgui.SetShape(idbox, idmesh); +# ---- launch SMESH +smeshgui = salome.ImportComponentGUI("SMESH") +smeshgui.Init(salome.myStudyId); # ---- create Hypothesis print "-------------------------- create Hypothesis" print "-------------------------- LocalLength" -hyp1=gen.CreateHypothesis("LocalLength") -hypLen1 = hyp1._narrow(SMESH.SMESH_LocalLength) + +hypLen1 = smesh.CreateHypothesis("LocalLength", "libStdMeshersEngine.so") hypLen1.SetLength(100) print hypLen1.GetName() print hypLen1.GetId() print hypLen1.GetLength() -idlength = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypLen1) ); +idlength = salome.ObjectToID(hypLen1) smeshgui.SetName(idlength, "Local_Length_100"); print "-------------------------- NumberOfSegments" -hyp2=gen.CreateHypothesis("NumberOfSegments") -hypNbSeg1=hyp2._narrow(SMESH.SMESH_NumberOfSegments) +hypNbSeg1 = smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so") hypNbSeg1.SetNumberOfSegments(7) print hypNbSeg1.GetName() print hypNbSeg1.GetId() print hypNbSeg1.GetNumberOfSegments() -idseg = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypNbSeg1) ); +idseg = salome.ObjectToID(hypNbSeg1) smeshgui.SetName(idseg, "NumberOfSegments_7"); print "-------------------------- MaxElementArea" -hyp3=gen.CreateHypothesis("MaxElementArea") -hypArea1=hyp3._narrow(SMESH.SMESH_MaxElementArea) +hypArea1 = smesh.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so") hypArea1.SetMaxElementArea(2500) print hypArea1.GetName() print hypArea1.GetId() print hypArea1.GetMaxElementArea() -idarea1 = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypArea1) ); +idarea1 = salome.ObjectToID(hypArea1) smeshgui.SetName(idarea1, "MaxElementArea_2500"); print "-------------------------- MaxElementArea" -hyp3=gen.CreateHypothesis("MaxElementArea") -hypArea2=hyp3._narrow(SMESH.SMESH_MaxElementArea) +hypArea2 = smesh.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so") hypArea2.SetMaxElementArea(500) print hypArea2.GetName() print hypArea2.GetId() print hypArea2.GetMaxElementArea() -idarea2 = smeshgui.AddNewHypothesis( salome.orb.object_to_string(hypArea2) ); +idarea2 = salome.ObjectToID(hypArea2) smeshgui.SetName(idarea2, "MaxElementArea_500"); print "-------------------------- Regular_1D" -alg1=gen.CreateHypothesis("Regular_1D") -algo1=alg1._narrow(SMESH.SMESH_Algo) -listHyp=algo1.GetCompatibleHypothesis() +algoReg = smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so") +listHyp=algoReg.GetCompatibleHypothesis() for hyp in listHyp: print hyp -algoReg=alg1._narrow(SMESH.SMESH_Regular_1D) print algoReg.GetName() print algoReg.GetId() -idreg = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(algoReg) ); +idreg = salome.ObjectToID(algoReg) smeshgui.SetName(idreg, "Regular_1D"); print "-------------------------- MEFISTO_2D" -alg2=gen.CreateHypothesis("MEFISTO_2D") -algo2=alg2._narrow(SMESH.SMESH_Algo) -listHyp=algo2.GetCompatibleHypothesis() +algoMef = smesh.CreateHypothesis("MEFISTO_2D", "libStdMeshersEngine.so") +listHyp=algoMef.GetCompatibleHypothesis() for hyp in listHyp: print hyp -algoMef=alg2._narrow(SMESH.SMESH_MEFISTO_2D) print algoMef.GetName() print algoMef.GetId() -idmef = smeshgui.AddNewAlgorithms( salome.orb.object_to_string(algoMef) ); +idmef = salome.ObjectToID(algoMef) smeshgui.SetName(idmef, "MEFISTO_2D"); +# ---- Init a Mesh with the box + +box=salome.IDToObject(idbox) +mesh=smesh.CreateMesh(box) + +idmesh = salome.ObjectToID(mesh) +smeshgui.SetName(idmesh, "Meshbox"); + +# ---- add hypothesis to box +print "-------------------------- add hypothesis to box" +mesh.AddHypothesis(box,algoReg) +mesh.AddHypothesis(box,hypNbSeg1) +mesh.AddHypothesis(box,algoMef) +mesh.AddHypothesis(box,hypArea1) + # ---- add hypothesis to edge print "-------------------------- add hypothesis to edge" edge=salome.IDToObject(idedge) -submesh=mesh.GetElementsOnShape(edge) -ret=mesh.AddHypothesis(edge,algoReg) -print ret -ret=mesh.AddHypothesis(edge,hypLen1) -print ret - -idsm1 = smeshgui.AddSubMeshOnShape( idmesh, - idedge, - salome.orb.object_to_string(submesh), - ShapeTypeEdge ) -smeshgui.SetName(idsm1, "SubMeshEdge") -smeshgui.SetAlgorithms( idsm1, idreg ); -smeshgui.SetHypothesis( idsm1, idlength ); +submesh = mesh.GetSubMesh(edge, "SubMeshEdge") +mesh.AddHypothesis(edge , algoReg) +mesh.AddHypothesis(edge, hypLen1) print "-------------------------- add hypothesis to face" -face=salome.IDToObject(idface) -submesh=mesh.GetElementsOnShape(face) -ret=mesh.AddHypothesis(face,hypArea2) -print ret - -idsm2 = smeshgui.AddSubMeshOnShape( idmesh, - idface, - salome.orb.object_to_string(submesh), - ShapeTypeFace ) -smeshgui.SetName(idsm2, "SubMeshFace") -smeshgui.SetHypothesis( idsm2, idarea2 ); - -# ---- add hypothesis to box +face = salome.IDToObject(idface) +submesh =mesh.GetSubMesh(face, "SubMeshFace") +mesh.AddHypothesis(face,hypArea2) -print "-------------------------- add hypothesis to box" -box=salome.IDToObject(idbox) -submesh=mesh.GetElementsOnShape(box) -ret=mesh.AddHypothesis(box,algoReg) -print ret -ret=mesh.AddHypothesis(box,hypNbSeg1) -print ret -ret=mesh.AddHypothesis(box,algoMef) -print ret -ret=mesh.AddHypothesis(box,hypArea1) -print ret - -smeshgui.SetAlgorithms( idmesh, idreg ); -smeshgui.SetHypothesis( idmesh, idseg ); -smeshgui.SetAlgorithms( idmesh, idmef ); -smeshgui.SetHypothesis( idmesh, idarea1 ); - -sg.updateObjBrowser(1); +salome.sg.updateObjBrowser(1); diff --git a/src/SMESH_SWIG/SMESH_test2.py b/src/SMESH_SWIG/SMESH_test2.py index dd58a63aa..1c58f73da 100644 --- a/src/SMESH_SWIG/SMESH_test2.py +++ b/src/SMESH_SWIG/SMESH_test2.py @@ -27,14 +27,14 @@ from SMESH_test1 import * # ---- compute box print "-------------------------- compute box" -ret=gen.Compute(mesh,idbox) +ret=smesh.Compute(mesh,box) print ret log=mesh.GetLog(0); # no erase trace for linelog in log: print linelog -sg.updateObjBrowser(1); +salome.sg.updateObjBrowser(1); # ---- compute edge diff --git a/src/SMESH_SWIG/SMESH_test3.py b/src/SMESH_SWIG/SMESH_test3.py index 4154040ce..65d7129e6 100644 --- a/src/SMESH_SWIG/SMESH_test3.py +++ b/src/SMESH_SWIG/SMESH_test3.py @@ -34,9 +34,6 @@ geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM") myBuilder = salome.myStudy.NewBuilder() from geompy import gg -smeshgui = salome.ImportComponentGUI("SMESH") -smeshgui.Init(salome.myStudyId); - ShapeTypeCompSolid = 1 ShapeTypeSolid = 2 ShapeTypeShell = 3 diff --git a/src/SMESH_SWIG/SMESH_test4.py b/src/SMESH_SWIG/SMESH_test4.py new file mode 100755 index 000000000..3a48db694 --- /dev/null +++ b/src/SMESH_SWIG/SMESH_test4.py @@ -0,0 +1,65 @@ +import salome +from geompy import gg +import geompy +import SMESH + +import StdMeshers + +ShapeTypeCompSolid = 1 +ShapeTypeSolid = 2 +ShapeTypeShell = 3 +ShapeTypeFace = 4 +ShapeTypeWire = 5 +ShapeTypeEdge = 6 +ShapeTypeVertex = 7 + +geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM") +smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH") + +geom.GetCurrentStudy(salome.myStudy._get_StudyId()) +smesh.SetCurrentStudy(salome.myStudy) + +box = geompy.MakeBox(0., 0., 0., 100., 200., 300.) +idbox = geompy.addToStudy(box,"box") + +subShapeList = geompy.SubShapeAll(box,ShapeTypeFace) +face = subShapeList[0] +name = geompy.SubShapeName( face._get_Name(), box._get_Name() ) +idface = geompy.addToStudyInFather(box,face,name) + +box = salome.IDToObject(idbox) +face = salome.IDToObject(idface) + +hyp1 = smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so") +hyp1.SetNumberOfSegments(10) +hyp2 = smesh.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so") +hyp2.SetMaxElementArea(10) +hyp3 = smesh.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so") +hyp3.SetMaxElementArea(100) + +algo1 = smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so") +algo2 = smesh.CreateHypothesis("MEFISTO_2D", "libStdMeshersEngine.so") + +mesh = smesh.CreateMesh(box) +mesh.AddHypothesis(box,hyp1) +mesh.AddHypothesis(box,hyp2) +mesh.AddHypothesis(box,algo1) +mesh.AddHypothesis(box,algo2) + +submesh = mesh.GetSubMesh(face, "SubMeshFace") +mesh.AddHypothesis(face,hyp1) +mesh.AddHypothesis(face,hyp3) +mesh.AddHypothesis(face,algo1) +mesh.AddHypothesis(face,algo2) + +smesh.Compute(mesh,box) + +faces = submesh.GetElementsByType(SMESH.FACE) +if len(faces) > 1: + print len(faces), len(faces)/2 + group1 = mesh.CreateGroup(SMESH.FACE,"Group of faces") + group2 = mesh.CreateGroup(SMESH.FACE,"Another group of faces") + group1.Add(faces[:int(len(faces)/2)]) + group2.Add(faces[int(len(faces)/2):]) + +salome.sg.updateObjBrowser(1) diff --git a/src/SMESH_SWIG/SMESH_test5.py b/src/SMESH_SWIG/SMESH_test5.py new file mode 100644 index 000000000..301917ddd --- /dev/null +++ b/src/SMESH_SWIG/SMESH_test5.py @@ -0,0 +1,79 @@ +# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +# +# +# +# File : SMESH_test1.py +# Module : SMESH + +import salome +import SMESH +import SALOMEDS +import CORBA +import os +import os.path + +def SetSObjName(theSObj,theName) : + ok, anAttr = theSObj.FindAttribute("AttributeName") + if ok: + aName = anAttr._narrow(SALOMEDS.AttributeName) + #print aName.__dict__ + aName.SetValue(theName) + +def ConvertMED2UNV(thePath,theFile) : + anInitFileName = thePath + theFile + aMeshes,aResult = smesh.CreateMeshesFromMED(anInitFileName) + print aResult, aMeshes + + for iMesh in range(len(aMeshes)) : + aMesh = aMeshes[iMesh] + anSObj = salome.ObjectToSObject(aMesh) + print anSObj.GetName(), + aFileName = anInitFileName + aFileName = os.path.basename(aFileName) + SetSObjName(anSObj,aFileName) + print anSObj.GetName() + + aFileName = thePath + theFile + "." + str(iMesh) + ".unv" + aMesh.ExportUNV(aFileName) + aMesh = smesh.CreateMeshesFromUNV(aFileName) + anSObj = salome.ObjectToSObject(aMesh) + print anSObj.GetName(), + os.remove(aFileName) + aFileName = os.path.basename(aFileName) + SetSObjName(anSObj,aFileName) + print anSObj.GetName() + +smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH") +smesh.SetCurrentStudy(salome.myStudy) + +aPath = os.getenv('KERNEL_ROOT_DIR') + '/examples/' +aListDir = os.listdir(aPath) +print aListDir + +for iFile in range(len(aListDir)) : + aFileName = aListDir[iFile]; + aName,anExt = os.path.splitext(aFileName) + if anExt == ".med" : + aFileName = os.path.basename(aFileName) + print aFileName + ConvertMED2UNV(aPath,aFileName) + #break + +salome.sg.updateObjBrowser(1); diff --git a/src/SMESH_SWIG/batchmode_mefisto.py b/src/SMESH_SWIG/batchmode_mefisto.py new file mode 100644 index 000000000..6fa30717e --- /dev/null +++ b/src/SMESH_SWIG/batchmode_mefisto.py @@ -0,0 +1,150 @@ +import os +import re + +import batchmode_salome +import batchmode_geompy +import batchmode_smesh + +geom = batchmode_geompy.geom +smesh = batchmode_smesh.smesh + +geom.GetCurrentStudy(batchmode_salome.myStudyId) +smesh.SetCurrentStudy(batchmode_salome.myStudy) + +ShapeType = batchmode_smesh.ShapeType + +import StdMeshers + +def CreateMesh (theFileName, area, len = None, nbseg = None): + + if not(os.path.isfile(theFileName)) or re.search("\.brep$", theFileName) is None : + print "Incorrect file name !" + return + + if (len is None) and (nbseg is None): + print "Define length or number of segments !" + return + + if (len is not None) and (nbseg is not None): + print "Only one Hypothesis (from length and number of segments) can be defined !" + return + + + # ---- Import shape from BREP file and add it to the study + shape_mesh = geom.ImportBREP(theFileName) + Id_shape = batchmode_geompy.addToStudy( shape_mesh, "shape_mesh") + + + + # ---- SMESH + + # ---- create Hypothesis + + print "-------------------------- create Hypothesis" + if (len is not None): + print "-------------------------- LocalLength" + hypLength1 = smesh.CreateHypothesis("LocalLength", "libStdMeshersEngine.so") + hypLength1.SetLength(len) + print "Hypothesis type: ", hypLength1.GetName() + print "Hypothesis ID: ", hypLength1.GetId() + print "Hypothesis Value: ", hypLength1.GetLength() + + if (nbseg is not None): + print "-------------------------- NumberOfSegments" + hypNbSeg1 = smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so") + hypNbSeg1.SetNumberOfSegments(nbseg) + print "Hypothesis type: ", hypNbSeg1.GetName() + print "Hypothesis ID: ", hypNbSeg1.GetId() + print "Hypothesis Value: ", hypNbSeg1.GetNumberOfSegments() + + + if (area == "LengthFromEdges"): + print "-------------------------- LengthFromEdges" + hypLengthFromEdges = smesh.CreateHypothesis("LengthFromEdges", "libStdMeshersEngine.so") + hypLengthFromEdges.SetMode(1) + print "Hypothesis type: ", hypLengthFromEdges.GetName() + print "Hypothesis ID: ", hypLengthFromEdges.GetId() + print "LengthFromEdges Mode: ", hypLengthFromEdges.GetMode() + + else: + print "-------------------------- MaxElementArea" + hypArea1 = smesh.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so") + hypArea1.SetMaxElementArea(area) + print "Hypothesis type: ", hypArea1.GetName() + print "Hypothesis ID: ", hypArea1.GetId() + print "Hypothesis Value: ", hypArea1.GetMaxElementArea() + + + + print "-------------------------- Regular_1D" + algoReg = smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so") + + listHyp = algoReg.GetCompatibleHypothesis() + for hyp in listHyp: + print hyp + + print "Algo name: ", algoReg.GetName() + print "Algo ID: ", algoReg.GetId() + + print "-------------------------- MEFISTO_2D" + algoMef = smesh.CreateHypothesis("MEFISTO_2D", "libStdMeshersEngine.so") + + listHyp=algoMef.GetCompatibleHypothesis() + for hyp in listHyp: + print hyp + + print "Algo name: ", algoMef.GetName() + print "Algo ID: ", algoMef.GetId() + + + + # ---- add hypothesis to shape + + print "-------------------------- add hypothesis to shape" + mesh = smesh.CreateMesh(shape_mesh) + + ret = mesh.AddHypothesis(shape_mesh, algoReg) + print "Add Regular_1D algo .... ", + print ret + + if (nbseg is not None): + ret=mesh.AddHypothesis(shape_mesh, hypNbSeg1) + print "Add Number Of Segements algo .... ", + print ret + + if (len is not None): + ret=mesh.AddHypothesis(shape_mesh,hypLength1) + print "Add Local Length algo .... ", + print ret + + ret=mesh.AddHypothesis(shape_mesh, algoMef) + print "Add MEFISTO_2D algo....", + print ret + + if (area == "LengthFromEdges"): + ret = mesh.AddHypothesis( shape_mesh, hypLengthFromEdges) # length from edge + print "Add Length From Edges algo .... ", + print ret + else: + ret=mesh.AddHypothesis(shape_mesh, hypArea1) + print "Add Max Triangle Area algo .... ", + print ret + + # ---- compute mesh + + print "-------------------------- compute mesh" + ret=smesh.Compute(mesh,shape_mesh) + print "Compute Mesh .... ", + print ret + log=mesh.GetLog(0); # no erase trace + #for linelog in log: + # print linelog + + print "------------ INFORMATION ABOUT MESH ------------" + + print "Number of nodes: ", mesh.NbNodes() + print "Number of edges: ", mesh.NbEdges() + print "Number of faces: ", mesh.NbFaces() + print "Number of triangles: ", mesh.NbTriangles() + + return mesh diff --git a/src/SMESH_SWIG/batchmode_smesh.py b/src/SMESH_SWIG/batchmode_smesh.py index eef9e1d50..899dc59af 100644 --- a/src/SMESH_SWIG/batchmode_smesh.py +++ b/src/SMESH_SWIG/batchmode_smesh.py @@ -22,13 +22,10 @@ if myStudyBuilder is None: father = myStudy.FindComponent("MESH") if father is None: father = myStudyBuilder.NewComponent("MESH") - A1 = myStudyBuilder.FindOrCreateAttribute(father, "AttributeName"); - FName = A1._narrow(SALOMEDS.AttributeName) - #FName.SetValue("Mesh") + FName = myStudyBuilder.FindOrCreateAttribute(father, "AttributeName"); Comp = modulecatalog.GetComponent( "SMESH" ) FName.SetValue( Comp._get_componentusername() ) - A2 = myStudyBuilder.FindOrCreateAttribute(father, "AttributePixMap"); - aPixmap = A2._narrow(SALOMEDS.AttributePixMap); + aPixmap = myStudyBuilder.FindOrCreateAttribute(father, "AttributePixMap"); aPixmap.SetPixMap( "ICON_OBJBROWSER_Mesh" ); myStudyBuilder.DefineComponentInstance(father,smesh) @@ -67,113 +64,111 @@ def Init(): pass #------------------------------------------------------------ def AddNewMesh(IOR): + # VSR: added temporarily - objects are published automatically by the engine + aSO = myStudy.FindObjectIOR( IOR ) + if aSO is not None: + return aSO.GetID() + # VSR ###################################################################### + res,HypothesisRoot = mySComponentMesh.FindSubObject ( Tag_HypothesisRoot ) if HypothesisRoot is None or res == 0: HypothesisRoot = myStudyBuilder.NewObjectToTag(mySComponentMesh, Tag_HypothesisRoot) - anAttr = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeName") - aName = anAttr._narrow(SALOMEDS.AttributeName) - aName.SetValue("Hypothesis Definition") - anAttr = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributePixMap") - aPixmap = anAttr._narrow(SALOMEDS.AttributePixMap) + aName = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeName") + aName.SetValue("Hypotheses") + aPixmap = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributePixMap") aPixmap.SetPixMap( "mesh_tree_hypo.png" ) - anAttr = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeSelectable") - aSelAttr = anAttr._narrow(SALOMEDS.AttributeSelectable) + aSelAttr = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeSelectable") aSelAttr.SetSelectable(0); res, AlgorithmsRoot = mySComponentMesh.FindSubObject (Tag_AlgorithmsRoot) if AlgorithmsRoot is None or res == 0: AlgorithmsRoot = myStudyBuilder.NewObjectToTag (mySComponentMesh, Tag_AlgorithmsRoot) - anAttr = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeName") - aName = anAttr._narrow(SALOMEDS.AttributeName) - aName.SetValue("Algorithms Definition"); - anAttr = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributePixMap"); - aPixmap = anAttr._narrow(SALOMEDS.AttributePixMap); + aName = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeName") + aName.SetValue("Algorithms"); + aPixmap = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributePixMap"); aPixmap.SetPixMap( "mesh_tree_algo.png" ); - anAttr = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeSelectable"); - aSelAttr = anAttr._narrow(SALOMEDS.AttributeSelectable); + aSelAttr = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeSelectable"); aSelAttr.SetSelectable(0); HypothesisRoot = HypothesisRoot._narrow(SALOMEDS.SObject) newMesh = myStudyBuilder.NewObject(mySComponentMesh) - newMesh = newMesh._narrow(SALOMEDS.SObject) - anAttr = myStudyBuilder.FindOrCreateAttribute(newMesh, "AttributePixMap") - aPixmap = anAttr._narrow(SALOMEDS.AttributePixMap) + aPixmap = myStudyBuilder.FindOrCreateAttribute(newMesh, "AttributePixMap") aPixmap.SetPixMap( "mesh_tree_mesh.png" ) - anAttr = myStudyBuilder.FindOrCreateAttribute(newMesh, "AttributeIOR") - anIOR = anAttr._narrow(SALOMEDS.AttributeIOR) + anIOR = myStudyBuilder.FindOrCreateAttribute(newMesh, "AttributeIOR") anIOR.SetValue(IOR) return newMesh.GetID() #------------------------------------------------------------ def AddNewHypothesis(IOR): + # VSR: added temporarily - objects are published automatically by the engine + aSO = myStudy.FindObjectIOR( IOR ) + if aSO is not None: + return aSO.GetID() + # VSR ###################################################################### + res, HypothesisRoot = mySComponentMesh.FindSubObject (Tag_HypothesisRoot) if HypothesisRoot is None or res == 0: HypothesisRoot = myStudyBuilder.NewObjectToTag (mySComponentMesh, Tag_HypothesisRoot) - anAttr = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeName"); - aName = anAttr._narrow(SALOMEDS.AttributeName); - aName.SetValue("Hypothesis Definition"); - anAttr = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeSelectable"); - aSelAttr = anAttr._narrow(SALOMEDS.AttributeSelectable); + aName = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeName"); + aName.SetValue("Hypotheses"); + aSelAttr = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeSelectable"); aSelAttr.SetSelectable(0); - anAttr = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributePixMap"); - aPixmap = anAttr._narrow(SALOMEDS.AttributePixMap); + aPixmap = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributePixMap"); aPixmap.SetPixMap( "mesh_tree_hypo.png" ); # Add New Hypothesis newHypo = myStudyBuilder.NewObject(HypothesisRoot) - newHypo = newHypo._narrow(SALOMEDS.SObject) - anAttr = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributePixMap") - aPixmap = anAttr._narrow(SALOMEDS.AttributePixMap) + aPixmap = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributePixMap") H = orb.string_to_object(IOR) - H = H._narrow( SMESH.SMESH_Hypothesis ); aType = H.GetName(); aPixmap.SetPixMap( "mesh_tree_hypo.png_" + aType ); - anAttr = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributeIOR"); - anIOR = anAttr._narrow(SALOMEDS.AttributeIOR); + anIOR = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributeIOR"); anIOR.SetValue(IOR); return newHypo.GetID(); #------------------------------------------------------------ def AddNewAlgorithms(IOR): + # VSR: added temporarily - objects are published automatically by the engine + aSO = myStudy.FindObjectIOR( IOR ) + if aSO is not None: + return aSO.GetID() + # VSR ###################################################################### + res, AlgorithmsRoot = mySComponentMesh.FindSubObject (Tag_AlgorithmsRoot) if AlgorithmsRoot is None or res == 0: AlgorithmsRoot = myStudyBuilde.NewObjectToTag (mySComponentMesh, Tag_AlgorithmsRoot) - anAttr = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeName") - aName = anAttr._narrow(SALOMEDS.AttributeName); - aName.SetValue("Algorithms Definition"); - anAttr = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeSelectable") - aSelAttr = anAttr._narrow(SALOMEDS.AttributeSelectable); + aName = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeName") + aName.SetValue("Algorithms"); + aSelAttr = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeSelectable") aSelAttr.SetSelectable(0); - anAttr = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributePixMap"); - aPixmap = anAttr._narrow(SALOMEDS.AttributePixMap); + aPixmap = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributePixMap"); aPixmap.SetPixMap( "mesh_tree_algo.png" ); # Add New Algorithms newHypo = myStudyBuilder.NewObject(AlgorithmsRoot) - newHypo = newHypo._narrow(SALOMEDS.SObject) - anAttr = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributePixMap"); + aPixmap = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributePixMap"); aPixmap = anAttr._narrow(SALOMEDS.AttributePixMap); H = orb.string_to_object(IOR) - H = H._narrow( SMESH.SMESH_Hypothesis); aType = H.GetName(); #QString in fact aPixmap.SetPixMap( "mesh_tree_algo.png_" + aType ); - anAttr = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributeIOR"); - anIOR = anAttr._narrow(SALOMEDS.AttributeIOR); + anIOR = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributeIOR"); anIOR.SetValue(IOR); return newHypo.GetID(); #------------------------------------------------------------ def SetShape(ShapeEntry, MeshEntry): - SO_MorSM = myStudy.FindObjectID( MeshEntry ) - SO_MorSM = SO_MorSM._narrow(SALOMEDS.SObject) SO_GeomShape = myStudy.FindObjectID( ShapeEntry ); - SO_GeomShape = SO_GeomShape._narrow(SALOMEDS.SObject) if SO_MorSM is not None and SO_GeomShape is not None : + # VSR: added temporarily - shape reference is published automatically by the engine + res, Ref = SO_MorSM.FindSubObject( Tag_RefOnShape ); + if res == 1 : + return; + # VSR ###################################################################### + SO = myStudyBuilder.NewObjectToTag (SO_MorSM, Tag_RefOnShape); - SO = SO._narrow(SALOMEDS.SObject) myStudyBuilder.Addreference (SO,SO_GeomShape); @@ -188,19 +183,28 @@ def SetHypothesis(Mesh_Or_SubMesh_Entry, Hypothesis_Entry): res, AHR = SO_MorSM.FindSubObject (Tag_RefOnAppliedHypothesis) if AHR is None or res == 0: AHR = myStudyBuilder.NewObjectToTag (SO_MorSM, Tag_RefOnAppliedHypothesis); - anAttr = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeName"); - aName = anAttr._narrow(SALOMEDS.AttributeName); - aName.SetValue("Applied Hypothesis"); - anAttr = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeSelectable"); - aSelAttr = anAttr._narrow(SALOMEDS.AttributeSelectable); + aName = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeName"); + + # The same name as in SMESH_Mesh_i::AddHypothesis() ################## + aName.SetValue("Applied hypotheses"); + + aSelAttr = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeSelectable"); aSelAttr.SetSelectable(0); - anAttr = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributePixMap"); - aPixmap = anAttr._narrow(SALOMEDS.AttributePixMap); + aPixmap = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributePixMap"); aPixmap.SetPixMap( "mesh_tree_hypo.png" ); - - SO = myStudyBuilder.NewObject(AHR); - SO = SO._narrow(SALOMEDS.SObject) - myStudyBuilder.Addreference (SO,SO_Hypothesis); + + # VSR: added temporarily - reference to applied hypothesis is published automatically by the engine + else : + it = myStudy.NewChildIterator(AHR); + while it.More() : + res, Ref = it.Value().ReferencedObject(); + if res and Ref is not None and Ref.GetID() == Hypothesis_Entry : + return; + it.Next(); + # VSR ###################################################################### + + SO = myStudyBuilder.NewObject(AHR); + myStudyBuilder.Addreference (SO,SO_Hypothesis); #------------------------------------------------------------ def SetAlgorithms(Mesh_Or_SubMesh_Entry, Algorithms_Entry): @@ -211,16 +215,26 @@ def SetAlgorithms(Mesh_Or_SubMesh_Entry, Algorithms_Entry): res, AHR = SO_MorSM.FindSubObject (Tag_RefOnAppliedAlgorithms); if AHR is None or res == 0: AHR = myStudyBuilder.NewObjectToTag (SO_MorSM, Tag_RefOnAppliedAlgorithms); - anAttr = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeName"); - aName = anAttr._narrow(SALOMEDS.AttributeName); - aName.SetValue("Applied Algorithm"); - anAttr = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeSelectable"); - aSelAttr = anAttr._narrow(SALOMEDS.AttributeSelectable); + aName = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeName"); + + # The same name as in SMESH_Mesh_i::AddHypothesis() ################## + aName.SetValue("Applied algorithms"); + + aSelAttr = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeSelectable"); aSelAttr.SetSelectable(0); - anAttr = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributePixMap"); - aPixmap = anAttr._narrow(SALOMEDS.AttributePixMap); + aPixmap = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributePixMap"); aPixmap.SetPixMap( "mesh_tree_algo.png" ); - + + # VSR: added temporarily - reference to applied hypothesis is published automatically by the engine + else : + it = myStudy.NewChildIterator(AHR); + while it.More() : + res, Ref = it.Value().ReferencedObject(); + if res and Ref is not None and Ref.GetID() == Algorithms_Entry : + return; + it.Next(); + # VSR ###################################################################### + SO = myStudyBuilder.NewObject(AHR); myStudyBuilder.Addreference (SO,SO_Algorithms); @@ -234,40 +248,41 @@ def UnSetHypothesis( Applied_Hypothesis_Entry ): #------------------------------------------------------------ def AddSubMesh ( SO_Mesh_Entry, SM_IOR, ST): + # VSR: added temporarily - objects are published automatically by the engine + aSO = myStudy.FindObjectIOR( SM_IOR ) + if aSO is not None: + return aSO.GetID() + # VSR ###################################################################### + SO_Mesh = myStudy.FindObjectID( SO_Mesh_Entry ) if ( SO_Mesh ) : if ST == ShapeTypeCompSolid : Tag_Shape = Tag_SubMeshOnSolid; - Name = "SubMeshes On Solid"; + Name = "SubMeshes on Solid"; elif ST == ShapeTypeFace : Tag_Shape = Tag_SubMeshOnFace; - Name = "SubMeshes On Face"; + Name = "SubMeshes on Face"; elif ST == ShapeTypeEdge : Tag_Shape = Tag_SubMeshOnEdge; - Name = "SubMeshes On Edge"; + Name = "SubMeshes on Edge"; elif ST == ShapeTypeVertex : Tag_Shape = Tag_SubMeshOnVertex; - Name = "SubMeshes On Vertex"; + Name = "SubMeshes on Vertex"; else : Tag_Shape = Tag_SubMeshOnCompound; - Name = "SubMeshes On Compound"; + Name = "SubMeshes on Compound"; res, SubmeshesRoot = SO_Mesh.FindSubObject (Tag_Shape) if SubmeshesRoot is None or res == 0: SubmeshesRoot = myStudyBuilder.NewObjectToTag (SO_Mesh, Tag_Shape); - anAttr = myStudyBuilder.FindOrCreateAttribute(SubmeshesRoot, "AttributeName"); - - aName = anAttr._narrow(SALOMEDS.AttributeName); + aName = myStudyBuilder.FindOrCreateAttribute(SubmeshesRoot, "AttributeName"); aName.SetValue(Name); - anAttr = myStudyBuilder.FindOrCreateAttribute(SubmeshesRoot, "AttributeSelectable"); - aSelAttr = anAttr._narrow(SALOMEDS.AttributeSelectable); + aSelAttr = myStudyBuilder.FindOrCreateAttribute(SubmeshesRoot, "AttributeSelectable"); aSelAttr.SetSelectable(0); SO = myStudyBuilder.NewObject (SubmeshesRoot); - SO = SO._narrow(SALOMEDS.SObject) - anAttr = myStudyBuilder.FindOrCreateAttribute(SO, "AttributeIOR"); - anIOR = anAttr._narrow(SALOMEDS.AttributeIOR); + anIOR = myStudyBuilder.FindOrCreateAttribute(SO, "AttributeIOR"); anIOR.SetValue(SM_IOR); return SO.GetID(); @@ -275,24 +290,28 @@ def AddSubMesh ( SO_Mesh_Entry, SM_IOR, ST): #------------------------------------------------------------ def AddSubMeshOnShape (Mesh_Entry, GeomShape_Entry, SM_IOR, ST) : - SO_GeomShape = myStudy.FindObjectID( GeomShape_Entry ); - if SO_GeomShape != None : - SM_Entry = AddSubMesh (Mesh_Entry,SM_IOR,ST); - SO_SM = myStudy.FindObjectID( SM_Entry ); - - if SO_SM != None : - SetShape (GeomShape_Entry, SM_Entry); - return SO_SM.GetID(); + # VSR: added temporarily - objects are published automatically by the engine + aSO = myStudy.FindObjectIOR( SM_IOR ) + if aSO is not None: + return aSO.GetID() + # VSR ###################################################################### + SO_GeomShape = myStudy.FindObjectID( GeomShape_Entry ); + if SO_GeomShape != None : + SM_Entry = AddSubMesh (Mesh_Entry,SM_IOR,ST); + SO_SM = myStudy.FindObjectID( SM_Entry ); + + if SO_SM != None : + SetShape (GeomShape_Entry, SM_Entry); + return SM_Entry; - return None; + return None; #------------------------------------------------------------ def SetName(Entry, Name): SO = myStudy.FindObjectID( Entry ); if SO != None : - anAttr = myStudyBuilder.FindOrCreateAttribute(SO, "AttributeName"); - aName = anAttr._narrow(SALOMEDS.AttributeName); + aName = myStudyBuilder.FindOrCreateAttribute(SO, "AttributeName"); aName.SetValue(Name); diff --git a/src/StdMeshers/Makefile.in b/src/StdMeshers/Makefile.in new file mode 100644 index 000000000..b7d66f8d1 --- /dev/null +++ b/src/StdMeshers/Makefile.in @@ -0,0 +1,81 @@ +# SMESH StdMeshers : implementaion of SMESH idl descriptions +# +# Copyright (C) 2003 CEA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +# +# +# +# File : Makefile.in +# Author : Julia DOROVSKIKH +# Module : SMESH +# $Header$ + +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl + + +@COMMENCE@ + +# header files +EXPORT_HEADERS = \ + StdMeshers_LengthFromEdges.hxx \ + StdMeshers_LocalLength.hxx \ + StdMeshers_NumberOfSegments.hxx \ + StdMeshers_MaxElementArea.hxx \ + StdMeshers_MaxElementVolume.hxx \ + StdMeshers_NotConformAllowed.hxx \ + StdMeshers_Regular_1D.hxx \ + StdMeshers_Quadrangle_2D.hxx \ + StdMeshers_MEFISTO_2D.hxx \ + StdMeshers_Hexa_3D.hxx + +EXPORT_PYSCRIPTS = + +# Libraries targets + +LIB = libStdMeshers.la + +LIB_SRC = \ + StdMeshers_LengthFromEdges.cxx \ + StdMeshers_LocalLength.cxx \ + StdMeshers_MaxElementArea.cxx \ + StdMeshers_MaxElementVolume.cxx \ + StdMeshers_NumberOfSegments.cxx \ + StdMeshers_NotConformAllowed.cxx \ + StdMeshers_Regular_1D.cxx \ + StdMeshers_Quadrangle_2D.cxx \ + StdMeshers_MEFISTO_2D.cxx \ + StdMeshers_Hexa_3D.cxx + +LIB_SERVER_IDL = + +LIB_CLIENT_IDL = + +# Executables targets +BIN = +BIN_SRC = + +# additionnal information to compil and link file +CPPFLAGS+= $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS) +CXXFLAGS+= $(OCC_CXXFLAGS) -I${KERNEL_ROOT_DIR}/include/salome + +LDFLAGS+= -lSMESHimpl -lMEFISTO2D -L${KERNEL_ROOT_DIR}/lib/salome + +@CONCLUDE@ diff --git a/src/StdMeshers/StdMeshers_Hexa_3D.cxx b/src/StdMeshers/StdMeshers_Hexa_3D.cxx new file mode 100644 index 000000000..6c631d0db --- /dev/null +++ b/src/StdMeshers/StdMeshers_Hexa_3D.cxx @@ -0,0 +1,1004 @@ +// SMESH SMESH : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_Hexa_3D.cxx +// Moved here from SMESH_Hexa_3D.cxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +using namespace std; +#include "StdMeshers_Hexa_3D.hxx" +#include "StdMeshers_Quadrangle_2D.hxx" +#include "SMESH_Gen.hxx" +#include "SMESH_Mesh.hxx" + +#include "SMDS_MeshElement.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_FacePosition.hxx" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "utilities.h" +#include "Utils_ExceptHandlers.hxx" + + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, int studyId, + SMESH_Gen * gen):SMESH_3D_Algo(hypId, studyId, gen) +{ + MESSAGE("StdMeshers_Hexa_3D::StdMeshers_Hexa_3D"); + _name = "Hexa_3D"; +// _shapeType = TopAbs_SOLID; + _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID); // 1 bit /shape type +// MESSAGE("_shapeType octal " << oct << _shapeType); + for (int i = 0; i < 6; i++) + _quads[i] = 0; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D() +{ + MESSAGE("StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D"); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool StdMeshers_Hexa_3D::CheckHypothesis + (SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus) +{ + MESSAGE("StdMeshers_Hexa_3D::CheckHypothesis"); + + bool isOk = true; + aStatus = SMESH_Hypothesis::HYP_OK; + + // nothing to check + + return isOk; +} + +//============================================================================= +/*! + * Hexahedron mesh on hexaedron like form + * -0. - shape and face mesh verification + * -1. - identify faces and vertices of the "cube" + * -2. - Algorithm from: + * "Application de l'interpolation transfinie à la création de maillages + * C0 ou G1 continus sur des triangles, quadrangles, tetraedres, pentaedres + * et hexaedres déformés." + * Alain PERONNET - 8 janvier 1999 + */ +//============================================================================= + +bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape)throw(SALOME_Exception) +{ + Unexpect aCatch(SalomeException); + MESSAGE("StdMeshers_Hexa_3D::Compute"); + + bool isOk = false; + SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape); + //const SMESHDS_SubMesh *& subMeshDS = theSubMesh->GetSubMeshDS(); + + // 0. - shape and face mesh verification + // 0.1 - shape must be a solid (or a shell) with 6 faces + MESSAGE("---"); + + vector < SMESH_subMesh * >meshFaces; + for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) + { + SMESH_subMesh *aSubMesh = aMesh.GetSubMeshContaining(exp.Current()); + ASSERT(aSubMesh); + meshFaces.push_back(aSubMesh); + } + if (meshFaces.size() != 6) + { + SCRUTE(meshFaces.size()); + ASSERT(0); + return false; + } + + // 0.2 - is each face meshed with Quadrangle_2D? (so, with a wire of 4 edges) + MESSAGE("---"); + + for (int i = 0; i < 6; i++) + { + TopoDS_Shape aShape = meshFaces[i]->GetSubShape(); + SMESH_Algo *algo = _gen->GetAlgo(aMesh, aShape); + string algoName = algo->GetName(); + if (algoName != "Quadrangle_2D") + { + // *** delete _quads + SCRUTE(algoName); + ASSERT(0); + return false; + } + StdMeshers_Quadrangle_2D *quadAlgo = + dynamic_cast < StdMeshers_Quadrangle_2D * >(algo); + ASSERT(quadAlgo); + try + { + _quads[i] = quadAlgo->CheckAnd2Dcompute(aMesh, aShape); + // *** to delete after usage + } + catch(SALOME_Exception & S_ex) + { + // *** delete _quads + // *** throw exception + ASSERT(0); + } + } + + // 1. - identify faces and vertices of the "cube" + // 1.1 - ancestor maps vertex->edges in the cube + MESSAGE("---"); + + TopTools_IndexedDataMapOfShapeListOfShape MS; + TopExp::MapShapesAndAncestors(aShape, TopAbs_VERTEX, TopAbs_EDGE, MS); + + // 1.2 - first face is choosen as face Y=0 of the unit cube + MESSAGE("---"); + + const TopoDS_Shape & aFace = meshFaces[0]->GetSubShape(); + const TopoDS_Face & F = TopoDS::Face(aFace); + + // 1.3 - identify the 4 vertices of the face Y=0: V000, V100, V101, V001 + MESSAGE("---"); + + int i = 0; + TopoDS_Edge E = _quads[0]->edge[i]; //edge will be Y=0,Z=0 on unit cube + double f, l; + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l); + TopoDS_Vertex VFirst, VLast; + TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l + bool isForward = + (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0); + + if (isForward) + { + _cube.V000 = VFirst; // will be (0,0,0) on the unit cube + _cube.V100 = VLast; // will be (1,0,0) on the unit cube + } + else + { + _cube.V000 = VLast; + _cube.V100 = VFirst; + } + + i = 1; + E = _quads[0]->edge[i]; + C2d = BRep_Tool::CurveOnSurface(E, F, f, l); + TopExp::Vertices(E, VFirst, VLast); + isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0); + if (isForward) + _cube.V101 = VLast; // will be (1,0,1) on the unit cube + else + _cube.V101 = VFirst; + + i = 2; + E = _quads[0]->edge[i]; + C2d = BRep_Tool::CurveOnSurface(E, F, f, l); + TopExp::Vertices(E, VFirst, VLast); + isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0); + if (isForward) + _cube.V001 = VLast; // will be (0,0,1) on the unit cube + else + _cube.V001 = VFirst; + + // 1.4 - find edge X=0, Z=0 (ancestor of V000 not in face Y=0) + // - find edge X=1, Z=0 (ancestor of V100 not in face Y=0) + // - find edge X=1, Z=1 (ancestor of V101 not in face Y=0) + // - find edge X=0, Z=1 (ancestor of V001 not in face Y=0) + MESSAGE("---"); + + TopoDS_Edge E_0Y0 = EdgeNotInFace(aMesh, aShape, F, _cube.V000, MS); + ASSERT(!E_0Y0.IsNull()); + + TopoDS_Edge E_1Y0 = EdgeNotInFace(aMesh, aShape, F, _cube.V100, MS); + ASSERT(!E_1Y0.IsNull()); + + TopoDS_Edge E_1Y1 = EdgeNotInFace(aMesh, aShape, F, _cube.V101, MS); + ASSERT(!E_1Y1.IsNull()); + + TopoDS_Edge E_0Y1 = EdgeNotInFace(aMesh, aShape, F, _cube.V001, MS); + ASSERT(!E_0Y1.IsNull()); + + // 1.5 - identify the 4 vertices in face Y=1: V010, V110, V111, V011 + MESSAGE("---"); + + TopExp::Vertices(E_0Y0, VFirst, VLast); + if (VFirst.IsSame(_cube.V000)) + _cube.V010 = VLast; + else + _cube.V010 = VFirst; + + TopExp::Vertices(E_1Y0, VFirst, VLast); + if (VFirst.IsSame(_cube.V100)) + _cube.V110 = VLast; + else + _cube.V110 = VFirst; + + TopExp::Vertices(E_1Y1, VFirst, VLast); + if (VFirst.IsSame(_cube.V101)) + _cube.V111 = VLast; + else + _cube.V111 = VFirst; + + TopExp::Vertices(E_0Y1, VFirst, VLast); + if (VFirst.IsSame(_cube.V001)) + _cube.V011 = VLast; + else + _cube.V011 = VFirst; + + // 1.6 - find remaining faces given 4 vertices + MESSAGE("---"); + + _indY0 = 0; + _cube.quad_Y0 = _quads[_indY0]; + + _indY1 = GetFaceIndex(aMesh, aShape, meshFaces, + _cube.V010, _cube.V011, _cube.V110, _cube.V111); + _cube.quad_Y1 = _quads[_indY1]; + + _indZ0 = GetFaceIndex(aMesh, aShape, meshFaces, + _cube.V000, _cube.V010, _cube.V100, _cube.V110); + _cube.quad_Z0 = _quads[_indZ0]; + + _indZ1 = GetFaceIndex(aMesh, aShape, meshFaces, + _cube.V001, _cube.V011, _cube.V101, _cube.V111); + _cube.quad_Z1 = _quads[_indZ1]; + + _indX0 = GetFaceIndex(aMesh, aShape, meshFaces, + _cube.V000, _cube.V001, _cube.V010, _cube.V011); + _cube.quad_X0 = _quads[_indX0]; + + _indX1 = GetFaceIndex(aMesh, aShape, meshFaces, + _cube.V100, _cube.V101, _cube.V110, _cube.V111); + _cube.quad_X1 = _quads[_indX1]; + + MESSAGE("---"); + + // 1.7 - get convertion coefs from face 2D normalized to 3D normalized + + Conv2DStruct cx0; // for face X=0 + Conv2DStruct cx1; // for face X=1 + Conv2DStruct cy0; + Conv2DStruct cy1; + Conv2DStruct cz0; + Conv2DStruct cz1; + + GetConv2DCoefs(*_cube.quad_X0, meshFaces[_indX0]->GetSubShape(), + _cube.V000, _cube.V010, _cube.V011, _cube.V001, cx0); + GetConv2DCoefs(*_cube.quad_X1, meshFaces[_indX1]->GetSubShape(), + _cube.V100, _cube.V110, _cube.V111, _cube.V101, cx1); + GetConv2DCoefs(*_cube.quad_Y0, meshFaces[_indY0]->GetSubShape(), + _cube.V000, _cube.V100, _cube.V101, _cube.V001, cy0); + GetConv2DCoefs(*_cube.quad_Y1, meshFaces[_indY1]->GetSubShape(), + _cube.V010, _cube.V110, _cube.V111, _cube.V011, cy1); + GetConv2DCoefs(*_cube.quad_Z0, meshFaces[_indZ0]->GetSubShape(), + _cube.V000, _cube.V100, _cube.V110, _cube.V010, cz0); + GetConv2DCoefs(*_cube.quad_Z1, meshFaces[_indZ1]->GetSubShape(), + _cube.V001, _cube.V101, _cube.V111, _cube.V011, cz1); + + // 1.8 - create a 3D structure for normalized values + + MESSAGE("---"); + int nbx = _cube.quad_Y0->nbPts[0]; + int nby = _cube.quad_Y0->nbPts[1]; + int nbz; + if (cx0.a1 != 0) + nbz = _cube.quad_X0->nbPts[1]; + else + nbz = _cube.quad_X0->nbPts[0]; + //SCRUTE(nbx); + //SCRUTE(nby); + //SCRUTE(nbz); + int nbxyz = nbx * nby * nbz; + Point3DStruct *np = new Point3DStruct[nbxyz]; + + // 1.9 - store node indexes of faces + + { + const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX0]->GetSubShape()); + + faceQuadStruct *quad = _cube.quad_X0; + int i = 0; // j = x/face , k = y/face + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; + + + SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + + while(itf->more()) + { + const SMDS_MeshNode * node = itf->next(); + const SMDS_FacePosition* fpos = + static_cast(node->GetPosition().get()); + double ri = fpos->GetUParameter(); + double rj = fpos->GetVParameter(); + int i1 = int (ri); + int j1 = int (rj); + int ij1 = j1 * nbdown + i1; + quad->uv_grid[ij1].node = node; + } + + for (int i1 = 0; i1 < nbdown; i1++) + for (int j1 = 0; j1 < nbright; j1++) + { + int ij1 = j1 * nbdown + i1; + int j = cx0.ia * i1 + cx0.ib * j1 + cx0.ic; // j = x/face + int k = cx0.ja * i1 + cx0.jb * j1 + cx0.jc; // k = y/face + int ijk = k * nbx * nby + j * nbx + i; + //MESSAGE(" "<uv_grid[ij1].node; + //SCRUTE(np[ijk].nodeId); + } + } + + { + const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX1]->GetSubShape()); + + SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + + faceQuadStruct *quad = _cube.quad_X1; + int i = nbx - 1; // j = x/face , k = y/face + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; + + while(itf->more()) + { + const SMDS_MeshNode * node = itf->next(); + const SMDS_FacePosition* fpos = + static_cast(node->GetPosition().get()); + double ri = fpos->GetUParameter(); + double rj = fpos->GetVParameter(); + int i1 = int (ri); + int j1 = int (rj); + int ij1 = j1 * nbdown + i1; + quad->uv_grid[ij1].node = node; + } + + for (int i1 = 0; i1 < nbdown; i1++) + for (int j1 = 0; j1 < nbright; j1++) + { + int ij1 = j1 * nbdown + i1; + int j = cx1.ia * i1 + cx1.ib * j1 + cx1.ic; // j = x/face + int k = cx1.ja * i1 + cx1.jb * j1 + cx1.jc; // k = y/face + int ijk = k * nbx * nby + j * nbx + i; + //MESSAGE(" "<uv_grid[ij1].node; + //SCRUTE(np[ijk].nodeId); + } + } + + { + const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY0]->GetSubShape()); + + SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + + faceQuadStruct *quad = _cube.quad_Y0; + int j = 0; // i = x/face , k = y/face + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; + + while(itf->more()) + { + const SMDS_MeshNode * node = itf->next(); + const SMDS_FacePosition * fpos = + static_cast(node->GetPosition().get()); + double ri = fpos->GetUParameter(); + double rj = fpos->GetVParameter(); + int i1 = int (ri); + int j1 = int (rj); + int ij1 = j1 * nbdown + i1; + quad->uv_grid[ij1].node = node; + } + + for (int i1 = 0; i1 < nbdown; i1++) + for (int j1 = 0; j1 < nbright; j1++) + { + int ij1 = j1 * nbdown + i1; + int i = cy0.ia * i1 + cy0.ib * j1 + cy0.ic; // i = x/face + int k = cy0.ja * i1 + cy0.jb * j1 + cy0.jc; // k = y/face + int ijk = k * nbx * nby + j * nbx + i; + //MESSAGE(" "<uv_grid[ij1].node; + //SCRUTE(np[ijk].nodeId); + } + } + + { + const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY1]->GetSubShape()); + + SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + + faceQuadStruct *quad = _cube.quad_Y1; + int j = nby - 1; // i = x/face , k = y/face + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; + + while(itf->more()) + { + const SMDS_MeshNode * node = itf->next(); + const SMDS_FacePosition* fpos = + static_cast(node->GetPosition().get()); + double ri = fpos->GetUParameter(); + double rj = fpos->GetVParameter(); + int i1 = int (ri); + int j1 = int (rj); + int ij1 = j1 * nbdown + i1; + quad->uv_grid[ij1].node = node; + } + + for (int i1 = 0; i1 < nbdown; i1++) + for (int j1 = 0; j1 < nbright; j1++) + { + int ij1 = j1 * nbdown + i1; + int i = cy1.ia * i1 + cy1.ib * j1 + cy1.ic; // i = x/face + int k = cy1.ja * i1 + cy1.jb * j1 + cy1.jc; // k = y/face + int ijk = k * nbx * nby + j * nbx + i; + //MESSAGE(" "<uv_grid[ij1].node; + //SCRUTE(np[ijk].nodeId); + } + } + + { + const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ0]->GetSubShape()); + + SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + + faceQuadStruct *quad = _cube.quad_Z0; + int k = 0; // i = x/face , j = y/face + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; + + while(itf->more()) + { + const SMDS_MeshNode * node = itf->next(); + const SMDS_FacePosition * fpos = + static_cast(node->GetPosition().get()); + double ri = fpos->GetUParameter(); + double rj = fpos->GetVParameter(); + int i1 = int (ri); + int j1 = int (rj); + int ij1 = j1 * nbdown + i1; + quad->uv_grid[ij1].node = node; + } + + for (int i1 = 0; i1 < nbdown; i1++) + for (int j1 = 0; j1 < nbright; j1++) + { + int ij1 = j1 * nbdown + i1; + int i = cz0.ia * i1 + cz0.ib * j1 + cz0.ic; // i = x/face + int j = cz0.ja * i1 + cz0.jb * j1 + cz0.jc; // j = y/face + int ijk = k * nbx * nby + j * nbx + i; + //MESSAGE(" "<uv_grid[ij1].node; + //SCRUTE(np[ijk].nodeId); + } + } + + { + const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ1]->GetSubShape()); + + SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); + + faceQuadStruct *quad = _cube.quad_Z1; + int k = nbz - 1; // i = x/face , j = y/face + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; + + while(itf->more()) + { + const SMDS_MeshNode * node = itf->next(); + const SMDS_FacePosition* fpos = + static_cast(node->GetPosition().get()); + double ri = fpos->GetUParameter(); + double rj = fpos->GetVParameter(); + int i1 = int (ri); + int j1 = int (rj); + int ij1 = j1 * nbdown + i1; + quad->uv_grid[ij1].node = node; + } + + for (int i1 = 0; i1 < nbdown; i1++) + for (int j1 = 0; j1 < nbright; j1++) + { + int ij1 = j1 * nbdown + i1; + int i = cz1.ia * i1 + cz1.ib * j1 + cz1.ic; // i = x/face + int j = cz1.ja * i1 + cz1.jb * j1 + cz1.jc; // j = y/face + int ijk = k * nbx * nby + j * nbx + i; + //MESSAGE(" "<uv_grid[ij1].node; + //SCRUTE(np[ijk].nodeId); + } + } + + // 2.0 - for each node of the cube: + // - get the 8 points 3D = 8 vertices of the cube + // - get the 12 points 3D on the 12 edges of the cube + // - get the 6 points 3D on the 6 faces with their ID + // - compute the point 3D + // - store the point 3D in SMESHDS, store its ID in 3D structure + + TopoDS_Shell aShell; + TopExp_Explorer exp(aShape, TopAbs_SHELL); + if (exp.More()) + { + aShell = TopoDS::Shell(exp.Current()); + } + else + { + MESSAGE("no shell..."); + ASSERT(0); + } + + Pt3 p000, p001, p010, p011, p100, p101, p110, p111; + Pt3 px00, px01, px10, px11; + Pt3 p0y0, p0y1, p1y0, p1y1; + Pt3 p00z, p01z, p10z, p11z; + Pt3 pxy0, pxy1, px0z, px1z, p0yz, p1yz; + + GetPoint(p000, 0, 0, 0, nbx, nby, nbz, np, meshDS); + GetPoint(p001, 0, 0, nbz - 1, nbx, nby, nbz, np, meshDS); + GetPoint(p010, 0, nby - 1, 0, nbx, nby, nbz, np, meshDS); + GetPoint(p011, 0, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS); + GetPoint(p100, nbx - 1, 0, 0, nbx, nby, nbz, np, meshDS); + GetPoint(p101, nbx - 1, 0, nbz - 1, nbx, nby, nbz, np, meshDS); + GetPoint(p110, nbx - 1, nby - 1, 0, nbx, nby, nbz, np, meshDS); + GetPoint(p111, nbx - 1, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS); + + for (int i = 1; i < nbx - 1; i++) + { + for (int j = 1; j < nby - 1; j++) + { + for (int k = 1; k < nbz - 1; k++) + { + // *** seulement maillage regulier + // 12 points on edges + GetPoint(px00, i, 0, 0, nbx, nby, nbz, np, meshDS); + GetPoint(px01, i, 0, nbz - 1, nbx, nby, nbz, np, meshDS); + GetPoint(px10, i, nby - 1, 0, nbx, nby, nbz, np, meshDS); + GetPoint(px11, i, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS); + + GetPoint(p0y0, 0, j, 0, nbx, nby, nbz, np, meshDS); + GetPoint(p0y1, 0, j, nbz - 1, nbx, nby, nbz, np, meshDS); + GetPoint(p1y0, nbx - 1, j, 0, nbx, nby, nbz, np, meshDS); + GetPoint(p1y1, nbx - 1, j, nbz - 1, nbx, nby, nbz, np, meshDS); + + GetPoint(p00z, 0, 0, k, nbx, nby, nbz, np, meshDS); + GetPoint(p01z, 0, nby - 1, k, nbx, nby, nbz, np, meshDS); + GetPoint(p10z, nbx - 1, 0, k, nbx, nby, nbz, np, meshDS); + GetPoint(p11z, nbx - 1, nby - 1, k, nbx, nby, nbz, np, meshDS); + + // 12 points on faces + GetPoint(pxy0, i, j, 0, nbx, nby, nbz, np, meshDS); + GetPoint(pxy1, i, j, nbz - 1, nbx, nby, nbz, np, meshDS); + GetPoint(px0z, i, 0, k, nbx, nby, nbz, np, meshDS); + GetPoint(px1z, i, nby - 1, k, nbx, nby, nbz, np, meshDS); + GetPoint(p0yz, 0, j, k, nbx, nby, nbz, np, meshDS); + GetPoint(p1yz, nbx - 1, j, k, nbx, nby, nbz, np, meshDS); + + int ijk = k * nbx * nby + j * nbx + i; + double x = double (i) / double (nbx - 1); // *** seulement + double y = double (j) / double (nby - 1); // *** maillage + double z = double (k) / double (nbz - 1); // *** regulier + + Pt3 X; + for (int i = 0; i < 3; i++) + { + X[i] = + (1 - x) * p0yz[i] + x * p1yz[i] + + (1 - y) * px0z[i] + y * px1z[i] + + (1 - z) * pxy0[i] + z * pxy1[i] + - (1 - x) * ((1 - y) * p00z[i] + y * p01z[i]) + - x * ((1 - y) * p10z[i] + y * p11z[i]) + - (1 - y) * ((1 - z) * px00[i] + z * px01[i]) + - y * ((1 - z) * px10[i] + z * px11[i]) + - (1 - z) * ((1 - x) * p0y0[i] + x * p1y0[i]) + - z * ((1 - x) * p0y1[i] + x * p1y1[i]) + + (1 - x) * ((1 - y) * ((1 - z) * p000[i] + z * p001[i]) + + y * ((1 - z) * p010[i] + z * p011[i])) + + x * ((1 - y) * ((1 - z) * p100[i] + z * p101[i]) + + y * ((1 - z) * p110[i] + z * p111[i])); + } + + SMDS_MeshNode * node = meshDS->AddNode(X[0], X[1], X[2]); + np[ijk].node = node; + //meshDS->SetNodeInVolume(node, TopoDS::Solid(aShape)); + meshDS->SetNodeInVolume(node, aShell); + } + } + } + + //2.1 - for each node of the cube (less 3 *1 Faces): + // - store hexahedron in SMESHDS + MESSAGE("Storing hexahedron into the DS"); + for (int i = 0; i < nbx - 1; i++) + for (int j = 0; j < nby - 1; j++) + for (int k = 0; k < nbz - 1; k++) + { + int n1 = k * nbx * nby + j * nbx + i; + int n2 = k * nbx * nby + j * nbx + i + 1; + int n3 = k * nbx * nby + (j + 1) * nbx + i + 1; + int n4 = k * nbx * nby + (j + 1) * nbx + i; + int n5 = (k + 1) * nbx * nby + j * nbx + i; + int n6 = (k + 1) * nbx * nby + j * nbx + i + 1; + int n7 = (k + 1) * nbx * nby + (j + 1) * nbx + i + 1; + int n8 = (k + 1) * nbx * nby + (j + 1) * nbx + i; + +// MESSAGE(" "<AddVolume(np[n1].node, + np[n2].node, + np[n3].node, + np[n4].node, + np[n5].node, + np[n6].node, + np[n7].node, + np[n8].node); + ; + meshDS->SetMeshElementOnShape(elt, aShell); + + // *** 5 tetrahedres ... verifier orientations, + // mettre en coherence &vec quadrangles-> triangles + // choisir afficher 1 parmi edges, face et volumes +// int tetra1 = meshDS->AddVolume(np[n1].nodeId, +// np[n2].nodeId, +// np[n4].nodeId, +// np[n5].nodeId); +// int tetra2 = meshDS->AddVolume(np[n2].nodeId, +// np[n3].nodeId, +// np[n4].nodeId, +// np[n7].nodeId); +// int tetra3 = meshDS->AddVolume(np[n5].nodeId, +// np[n6].nodeId, +// np[n7].nodeId, +// np[n2].nodeId); +// int tetra4 = meshDS->AddVolume(np[n5].nodeId, +// np[n7].nodeId, +// np[n8].nodeId, +// np[n4].nodeId); +// int tetra5 = meshDS->AddVolume(np[n5].nodeId, +// np[n7].nodeId, +// np[n2].nodeId, +// np[n4].nodeId); + + } + + MESSAGE("End of StdMeshers_Hexa_3D::Compute()"); + return true; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +void StdMeshers_Hexa_3D::GetPoint(Pt3 p, int i, int j, int k, int nbx, int nby, + int nbz, Point3DStruct * np, const SMESHDS_Mesh * meshDS) +{ + int ijk = k * nbx * nby + j * nbx + i; + const SMDS_MeshNode * node = np[ijk].node; + p[0] = node->X(); + p[1] = node->Y(); + p[2] = node->Z(); + //MESSAGE(" "<&meshFaces, + const TopoDS_Vertex & V0, + const TopoDS_Vertex & V1, + const TopoDS_Vertex & V2, const TopoDS_Vertex & V3) +{ + MESSAGE("StdMeshers_Hexa_3D::GetFaceIndex"); + int faceIndex = -1; + for (int i = 1; i < 6; i++) + { + const TopoDS_Shape & aFace = meshFaces[i]->GetSubShape(); + //const TopoDS_Face& F = TopoDS::Face(aFace); + TopTools_IndexedMapOfShape M; + TopExp::MapShapes(aFace, TopAbs_VERTEX, M); + bool verticesInShape = false; + if (M.Contains(V0)) + if (M.Contains(V1)) + if (M.Contains(V2)) + if (M.Contains(V3)) + verticesInShape = true; + if (verticesInShape) + { + faceIndex = i; + break; + } + } + ASSERT(faceIndex > 0); + SCRUTE(faceIndex); + return faceIndex; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +TopoDS_Edge + StdMeshers_Hexa_3D::EdgeNotInFace(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + const TopoDS_Face & aFace, + const TopoDS_Vertex & aVertex, + const TopTools_IndexedDataMapOfShapeListOfShape & MS) +{ + MESSAGE("StdMeshers_Hexa_3D::EdgeNotInFace"); + TopTools_IndexedDataMapOfShapeListOfShape MF; + TopExp::MapShapesAndAncestors(aFace, TopAbs_VERTEX, TopAbs_EDGE, MF); + const TopTools_ListOfShape & ancestorsInSolid = MS.FindFromKey(aVertex); + const TopTools_ListOfShape & ancestorsInFace = MF.FindFromKey(aVertex); + SCRUTE(ancestorsInSolid.Extent()); + SCRUTE(ancestorsInFace.Extent()); + ASSERT(ancestorsInSolid.Extent() == 6); // 6 (edges doublees) + ASSERT(ancestorsInFace.Extent() == 2); + + TopoDS_Edge E; + E.Nullify(); + TopTools_ListIteratorOfListOfShape its(ancestorsInSolid); + for (; its.More(); its.Next()) + { + TopoDS_Shape ancestor = its.Value(); + TopTools_ListIteratorOfListOfShape itf(ancestorsInFace); + bool isInFace = false; + for (; itf.More(); itf.Next()) + { + TopoDS_Shape ancestorInFace = itf.Value(); + if (ancestorInFace.IsSame(ancestor)) + { + isInFace = true; + break; + } + } + if (!isInFace) + { + E = TopoDS::Edge(ancestor); + break; + } + } + return E; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +void StdMeshers_Hexa_3D::GetConv2DCoefs(const faceQuadStruct & quad, + const TopoDS_Shape & aShape, + const TopoDS_Vertex & V0, + const TopoDS_Vertex & V1, + const TopoDS_Vertex & V2, const TopoDS_Vertex & V3, Conv2DStruct & conv) +{ + MESSAGE("StdMeshers_Hexa_3D::GetConv2DCoefs"); + const TopoDS_Face & F = TopoDS::Face(aShape); + TopoDS_Edge E = quad.edge[0]; + double f, l; + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l); + TopoDS_Vertex VFirst, VLast; + TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l + bool isForward = (((l - f) * (quad.last[0] - quad.first[0])) > 0); + TopoDS_Vertex VA, VB; + if (isForward) + { + VA = VFirst; + VB = VLast; + } + else + { + VA = VLast; + VB = VFirst; + } + int a1, b1, c1, a2, b2, c2; + if (VA.IsSame(V0)) + if (VB.IsSame(V1)) + { + a1 = 1; + b1 = 0; + c1 = 0; // x + a2 = 0; + b2 = 1; + c2 = 0; // y + } + else + { + ASSERT(VB.IsSame(V3)); + a1 = 0; + b1 = 1; + c1 = 0; // y + a2 = 1; + b2 = 0; + c2 = 0; // x + } + if (VA.IsSame(V1)) + if (VB.IsSame(V2)) + { + a1 = 0; + b1 = -1; + c1 = 1; // 1-y + a2 = 1; + b2 = 0; + c2 = 0; // x + } + else + { + ASSERT(VB.IsSame(V0)); + a1 = -1; + b1 = 0; + c1 = 1; // 1-x + a2 = 0; + b2 = 1; + c2 = 0; // y + } + if (VA.IsSame(V2)) + if (VB.IsSame(V3)) + { + a1 = -1; + b1 = 0; + c1 = 1; // 1-x + a2 = 0; + b2 = -1; + c2 = 1; // 1-y + } + else + { + ASSERT(VB.IsSame(V1)); + a1 = 0; + b1 = -1; + c1 = 1; // 1-y + a2 = -1; + b2 = 0; + c2 = 1; // 1-x + } + if (VA.IsSame(V3)) + if (VB.IsSame(V0)) + { + a1 = 0; + b1 = 1; + c1 = 0; // y + a2 = -1; + b2 = 0; + c2 = 1; // 1-x + } + else + { + ASSERT(VB.IsSame(V2)); + a1 = 1; + b1 = 0; + c1 = 0; // x + a2 = 0; + b2 = -1; + c2 = 1; // 1-y + } + MESSAGE("X = " << c1 << "+ " << a1 << "*x + " << b1 << "*y"); + MESSAGE("Y = " << c2 << "+ " << a2 << "*x + " << b2 << "*y"); + conv.a1 = a1; + conv.b1 = b1; + conv.c1 = c1; + conv.a2 = a2; + conv.b2 = b2; + conv.c2 = c2; + + int nbdown = quad.nbPts[0]; + int nbright = quad.nbPts[1]; + conv.ia = int (a1); + conv.ib = int (b1); + conv.ic = + int (c1 * a1 * a1) * (nbdown - 1) + int (c1 * b1 * b1) * (nbright - 1); + conv.ja = int (a2); + conv.jb = int (b2); + conv.jc = + int (c2 * a2 * a2) * (nbdown - 1) + int (c2 * b2 * b2) * (nbright - 1); + MESSAGE("I " << conv.ia << " " << conv.ib << " " << conv.ic); + MESSAGE("J " << conv.ja << " " << conv.jb << " " << conv.jc); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & StdMeshers_Hexa_3D::SaveTo(ostream & save) +{ + return save; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & StdMeshers_Hexa_3D::LoadFrom(istream & load) +{ + return load; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & operator <<(ostream & save, StdMeshers_Hexa_3D & hyp) +{ + return hyp.SaveTo( save ); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & operator >>(istream & load, StdMeshers_Hexa_3D & hyp) +{ + return hyp.LoadFrom( load ); +} diff --git a/src/StdMeshers/StdMeshers_Hexa_3D.hxx b/src/StdMeshers/StdMeshers_Hexa_3D.hxx new file mode 100644 index 000000000..a9e20459c --- /dev/null +++ b/src/StdMeshers/StdMeshers_Hexa_3D.hxx @@ -0,0 +1,140 @@ +// SMESH SMESH : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_Hexa_3D.hxx +// Moved here from SMESH_Hexa_3D.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#ifndef _SMESH_HEXA_3D_HXX_ +#define _SMESH_HEXA_3D_HXX_ + +#include "SMESH_3D_Algo.hxx" +#include "SMESH_Mesh.hxx" +#include "StdMeshers_Quadrangle_2D.hxx" +#include "Utils_SALOME_Exception.hxx" + +typedef struct point3Dstruct +{ + const SMDS_MeshNode * node; +} Point3DStruct; + +typedef double Pt3[3]; + +typedef struct conv2dstruct +{ + double a1; // X = a1*x + b1*y + c1 + double b1; // Y = a2*x + b2*y + c2 + double c1; // a1, b1 a2, b2 in {-1,0,1} + double a2; // c1, c2 in {0,1} + double b2; + double c2; + int ia; // I = ia*i + ib*j + ic + int ib; + int ic; + int ja; // J = ja*i + jb*j + jc + int jb; + int jc; +} Conv2DStruct; + +typedef struct cubeStruct +{ + TopoDS_Vertex V000; + TopoDS_Vertex V001; + TopoDS_Vertex V010; + TopoDS_Vertex V011; + TopoDS_Vertex V100; + TopoDS_Vertex V101; + TopoDS_Vertex V110; + TopoDS_Vertex V111; + faceQuadStruct* quad_X0; + faceQuadStruct* quad_X1; + faceQuadStruct* quad_Y0; + faceQuadStruct* quad_Y1; + faceQuadStruct* quad_Z0; + faceQuadStruct* quad_Z1; + Point3DStruct* np; // normalised 3D coordinates +} CubeStruct; + +class StdMeshers_Hexa_3D: + public SMESH_3D_Algo +{ +public: + StdMeshers_Hexa_3D(int hypId, int studyId, SMESH_Gen* gen); + virtual ~StdMeshers_Hexa_3D(); + + virtual bool CheckHypothesis(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus); + + virtual bool Compute(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape) + throw (SALOME_Exception); + + ostream & SaveTo(ostream & save); + istream & LoadFrom(istream & load); + friend ostream & operator << (ostream & save, StdMeshers_Hexa_3D & hyp); + friend istream & operator >> (istream & load, StdMeshers_Hexa_3D & hyp); + +protected: + TopoDS_Edge + EdgeNotInFace(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + const TopoDS_Face& aFace, + const TopoDS_Vertex& aVertex, + const TopTools_IndexedDataMapOfShapeListOfShape& MS); + + int GetFaceIndex(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + const vector& meshFaces, + const TopoDS_Vertex& V0, + const TopoDS_Vertex& V1, + const TopoDS_Vertex& V2, + const TopoDS_Vertex& V3); + + void GetConv2DCoefs(const faceQuadStruct& quad, + const TopoDS_Shape& aShape, + const TopoDS_Vertex& V0, + const TopoDS_Vertex& V1, + const TopoDS_Vertex& V2, + const TopoDS_Vertex& V3, + Conv2DStruct& conv); + + void GetPoint(Pt3 p, + int i, int j, int k, + int nbx, int nby, int nbz, + Point3DStruct *np, + const SMESHDS_Mesh* meshDS); + + CubeStruct _cube; + FaceQuadStruct* _quads[6]; + int _indX0; + int _indX1; + int _indY0; + int _indY1; + int _indZ0; + int _indZ1; +}; + +#endif diff --git a/src/StdMeshers/StdMeshers_LengthFromEdges.cxx b/src/StdMeshers/StdMeshers_LengthFromEdges.cxx new file mode 100644 index 000000000..f21f199f5 --- /dev/null +++ b/src/StdMeshers/StdMeshers_LengthFromEdges.cxx @@ -0,0 +1,139 @@ +// SMESH SMESH : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_LengthFromEdges.cxx +// Moved here from SMESH_LengthFromEdges.cxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +using namespace std; +#include "StdMeshers_LengthFromEdges.hxx" +#include "utilities.h" + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_LengthFromEdges::StdMeshers_LengthFromEdges(int hypId, int studyId, SMESH_Gen* gen) + : SMESH_Hypothesis(hypId, studyId, gen) +{ + _mode =1; + _name = "LengthFromEdges"; +// SCRUTE(_name); +// SCRUTE(&_name); + _param_algo_dim = 2; // is used by SMESH_MEFISTO_2D +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_LengthFromEdges::~StdMeshers_LengthFromEdges() +{ +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +void StdMeshers_LengthFromEdges::SetMode(int mode) + throw (SALOME_Exception) +{ + int oldMode = _mode; + if (mode <= 0) + throw SALOME_Exception(LOCALIZED("mode must be positive")); + _mode = mode; + if (oldMode != _mode) + NotifySubMeshesHypothesisModification(); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +int StdMeshers_LengthFromEdges::GetMode() +{ + return _mode; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & StdMeshers_LengthFromEdges::SaveTo(ostream & save) +{ + save << this->_mode; + return save; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & StdMeshers_LengthFromEdges::LoadFrom(istream & load) +{ + bool isOK = true; + int a; + isOK = (load >> a); + if (isOK) + this->_mode = a; + else + load.clear(ios::badbit | load.rdstate()); + return load; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & operator << (ostream & save, StdMeshers_LengthFromEdges & hyp) +{ + return hyp.SaveTo( save ); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & operator >> (istream & load, StdMeshers_LengthFromEdges & hyp) +{ + return hyp.LoadFrom( load ); +} + diff --git a/src/StdMeshers/StdMeshers_LengthFromEdges.hxx b/src/StdMeshers/StdMeshers_LengthFromEdges.hxx new file mode 100644 index 000000000..d514e7c94 --- /dev/null +++ b/src/StdMeshers/StdMeshers_LengthFromEdges.hxx @@ -0,0 +1,57 @@ +// SMESH SMESH : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_LengthFromEdges.hxx +// Moved here from SMESH_LengthFromEdges.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#ifndef _SMESH_LENGTHFROMEDGES_HXX_ +#define _SMESH_LENGTHFROMEDGES_HXX_ + +#include "SMESH_Hypothesis.hxx" +#include "Utils_SALOME_Exception.hxx" + +class StdMeshers_LengthFromEdges: + public SMESH_Hypothesis +{ +public: + StdMeshers_LengthFromEdges(int hypId, int studyId, SMESH_Gen* gen); + virtual ~StdMeshers_LengthFromEdges(); + + void SetMode(int mode) + throw (SALOME_Exception); + + int GetMode(); + + virtual ostream & SaveTo(ostream & save); + virtual istream & LoadFrom(istream & load); + friend ostream & operator << (ostream & save, StdMeshers_LengthFromEdges & hyp); + friend istream & operator >> (istream & load, StdMeshers_LengthFromEdges & hyp); + +protected: + int _mode; +}; + +#endif diff --git a/src/SMESH_I/SMESH_NumberOfSegments_i.cxx b/src/StdMeshers/StdMeshers_LocalLength.cxx similarity index 55% rename from src/SMESH_I/SMESH_NumberOfSegments_i.cxx rename to src/StdMeshers/StdMeshers_LocalLength.cxx index 74bff913d..457d8d80c 100644 --- a/src/SMESH_I/SMESH_NumberOfSegments_i.cxx +++ b/src/StdMeshers/StdMeshers_LocalLength.cxx @@ -1,4 +1,4 @@ -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// SMESH SMESH : implementaion of SMESH idl descriptions // // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -21,36 +21,40 @@ // // // -// File : SMESH_NumberOfSegments_i.cxx +// File : StdMeshers_LocalLength.cxx +// Moved here from SMESH_LocalLength.cxx // Author : Paul RASCLE, EDF // Module : SMESH // $Header$ using namespace std; -using namespace std; -#include "SMESH_NumberOfSegments_i.hxx" -#include "SMESH_Gen.hxx" -#include "SMESH_HypothesisFactory.hxx" - -#include "Utils_CorbaException.hxx" +#include "StdMeshers_LocalLength.hxx" #include "utilities.h" //============================================================================= /*! - * Constructor: - * _name is related to the class name: prefix = SMESH_ ; suffix = _i . + * + */ +//============================================================================= + +StdMeshers_LocalLength::StdMeshers_LocalLength(int hypId, int studyId, + SMESH_Gen * gen):SMESH_Hypothesis(hypId, studyId, gen) +{ + _length = 1.; + _name = "LocalLength"; +// SCRUTE(_name); +// SCRUTE(&_name); + _param_algo_dim = 1; // is used by SMESH_Regular_1D +} + +//============================================================================= +/*! + * */ //============================================================================= -SMESH_NumberOfSegments_i::SMESH_NumberOfSegments_i(const char* anHyp, - int studyId, - ::SMESH_Gen* genImpl) +StdMeshers_LocalLength::~StdMeshers_LocalLength() { - MESSAGE("SMESH_NumberOfSegments_i::SMESH_NumberOfSegments_i"); - _impl= new ::SMESH_NumberOfSegments(genImpl->_hypothesisFactory.GetANewId(), - studyId, - genImpl); - _baseImpl = _impl; } //============================================================================= @@ -59,8 +63,14 @@ SMESH_NumberOfSegments_i::SMESH_NumberOfSegments_i(const char* anHyp, */ //============================================================================= -SMESH_NumberOfSegments_i::~SMESH_NumberOfSegments_i() +void StdMeshers_LocalLength::SetLength(double length) throw(SALOME_Exception) { + double oldLength = _length; + if (length <= 0) + throw SALOME_Exception(LOCALIZED("length must be positive")); + _length = length; + if (oldLength != _length) + NotifySubMeshesHypothesisModification(); } //============================================================================= @@ -69,20 +79,9 @@ SMESH_NumberOfSegments_i::~SMESH_NumberOfSegments_i() */ //============================================================================= -void -SMESH_NumberOfSegments_i::SetNumberOfSegments(CORBA::Long segmentsNumber) - throw (SALOME::SALOME_Exception) +double StdMeshers_LocalLength::GetLength() const { - ASSERT(_impl); - try - { - _impl->SetNumberOfSegments(segmentsNumber); - } - catch (SALOME_Exception& S_ex) - { - THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), \ - SALOME::BAD_PARAM); - } + return _length; } //============================================================================= @@ -91,10 +90,10 @@ SMESH_NumberOfSegments_i::SetNumberOfSegments(CORBA::Long segmentsNumber) */ //============================================================================= -CORBA::Long SMESH_NumberOfSegments_i::GetNumberOfSegments() +ostream & StdMeshers_LocalLength::SaveTo(ostream & save) { - ASSERT(_impl); - return _impl->GetNumberOfSegments(); + save << this->_length; + return save; } //============================================================================= @@ -103,20 +102,16 @@ CORBA::Long SMESH_NumberOfSegments_i::GetNumberOfSegments() */ //============================================================================= -void -SMESH_NumberOfSegments_i::SetScaleFactor(CORBA::Double scaleFactor) - throw (SALOME::SALOME_Exception) +istream & StdMeshers_LocalLength::LoadFrom(istream & load) { - ASSERT(_impl); - try - { - _impl->SetScaleFactor(scaleFactor); - } - catch (SALOME_Exception& S_ex) - { - THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), \ - SALOME::BAD_PARAM); - } + bool isOK = true; + double a; + isOK = (load >> a); + if (isOK) + this->_length = a; + else + load.clear(ios::badbit | load.rdstate()); + return load; } //============================================================================= @@ -125,9 +120,18 @@ SMESH_NumberOfSegments_i::SetScaleFactor(CORBA::Double scaleFactor) */ //============================================================================= -CORBA::Double SMESH_NumberOfSegments_i::GetScaleFactor() +ostream & operator <<(ostream & save, StdMeshers_LocalLength & hyp) { - ASSERT(_impl); - return _impl->GetScaleFactor(); + return hyp.SaveTo( save ); } +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & operator >>(istream & load, StdMeshers_LocalLength & hyp) +{ + return hyp.LoadFrom( load ); +} diff --git a/src/StdMeshers/StdMeshers_LocalLength.hxx b/src/StdMeshers/StdMeshers_LocalLength.hxx new file mode 100644 index 000000000..aba58e51a --- /dev/null +++ b/src/StdMeshers/StdMeshers_LocalLength.hxx @@ -0,0 +1,55 @@ +// SMESH SMESH : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_LocalLength.hxx +// Moved here from SMESH_LocalLength.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#ifndef _SMESH_LOCALLENGTH_HXX_ +#define _SMESH_LOCALLENGTH_HXX_ + +#include "SMESH_Hypothesis.hxx" +#include "Utils_SALOME_Exception.hxx" + +class StdMeshers_LocalLength:public SMESH_Hypothesis +{ + public: + StdMeshers_LocalLength(int hypId, int studyId, SMESH_Gen * gen); + virtual ~ StdMeshers_LocalLength(); + + void SetLength(double length) throw(SALOME_Exception); + + double GetLength() const; + + virtual ostream & SaveTo(ostream & save); + virtual istream & LoadFrom(istream & load); + friend ostream & operator <<(ostream & save, StdMeshers_LocalLength & hyp); + friend istream & operator >>(istream & load, StdMeshers_LocalLength & hyp); + + protected: + double _length; +}; + +#endif diff --git a/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx new file mode 100644 index 000000000..6229e4c6d --- /dev/null +++ b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx @@ -0,0 +1,643 @@ +// SMESH SMESH : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_MEFISTO_2D.cxx +// Moved here from SMESH_MEFISTO_2D.cxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +using namespace std; +#include "StdMeshers_MEFISTO_2D.hxx" +#include "SMESH_Gen.hxx" +#include "SMESH_Mesh.hxx" + +#include "StdMeshers_MaxElementArea.hxx" +#include "StdMeshers_LengthFromEdges.hxx" + +#include "Rn.h" +#include "aptrte.h" + +#include "SMDS_MeshElement.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_EdgePosition.hxx" +#include "SMDS_FacePosition.hxx" + +#include "utilities.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D(int hypId, int studyId, + SMESH_Gen * gen):SMESH_2D_Algo(hypId, studyId, gen) +{ + MESSAGE("StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D"); + _name = "MEFISTO_2D"; +// _shapeType = TopAbs_FACE; + _shapeType = (1 << TopAbs_FACE); + _compatibleHypothesis.push_back("MaxElementArea"); + _compatibleHypothesis.push_back("LengthFromEdges"); + + _edgeLength = 0; + _maxElementArea = 0; + _hypMaxElementArea = NULL; + _hypLengthFromEdges = NULL; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D() +{ + MESSAGE("StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D"); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool StdMeshers_MEFISTO_2D::CheckHypothesis + (SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus) +{ + //MESSAGE("StdMeshers_MEFISTO_2D::CheckHypothesis"); + + _hypMaxElementArea = NULL; + _hypLengthFromEdges = NULL; + + list ::const_iterator itl; + const SMESHDS_Hypothesis *theHyp; + + const list &hyps = GetUsedHypothesis(aMesh, aShape); + int nbHyp = hyps.size(); + if (!nbHyp) + { + aStatus = SMESH_Hypothesis::HYP_MISSING; + return false; // can't work with no hypothesis + } + + itl = hyps.begin(); + theHyp = (*itl); // use only the first hypothesis + + string hypName = theHyp->GetName(); + int hypId = theHyp->GetID(); + //SCRUTE(hypName); + + bool isOk = false; + + if (hypName == "MaxElementArea") + { + _hypMaxElementArea = static_cast(theHyp); + ASSERT(_hypMaxElementArea); + _maxElementArea = _hypMaxElementArea->GetMaxArea(); + _edgeLength = 0; + isOk = true; + aStatus = SMESH_Hypothesis::HYP_OK; + } + + else if (hypName == "LengthFromEdges") + { + _hypLengthFromEdges = static_cast(theHyp); + ASSERT(_hypLengthFromEdges); + _edgeLength = 0; + _maxElementArea = 0; + isOk = true; + aStatus = SMESH_Hypothesis::HYP_OK; + } + else + aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE; + + if (isOk) + { + isOk = false; + if (_maxElementArea > 0) + { + _edgeLength = 2 * sqrt(_maxElementArea); // triangles : minorant + isOk = true; + } + else + isOk = (_hypLengthFromEdges != NULL); // **** check mode + if (!isOk) + aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER; + } + + //SCRUTE(_edgeLength); + //SCRUTE(_maxElementArea); + return isOk; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) +{ + MESSAGE("StdMeshers_MEFISTO_2D::Compute"); + + if (_hypLengthFromEdges) + _edgeLength = ComputeEdgeElementLength(aMesh, aShape); + + bool isOk = false; + const SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape); + + const TopoDS_Face & FF = TopoDS::Face(aShape); + bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD); + TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD)); + + Z nblf; //nombre de lignes fermees (enveloppe en tete) + Z *nudslf = NULL; //numero du dernier sommet de chaque ligne fermee + R2 *uvslf = NULL; + Z nbpti = 0; //nombre points internes futurs sommets de la triangulation + R2 *uvpti = NULL; + + Z nbst; + R2 *uvst = NULL; + Z nbt; + Z *nust = NULL; + Z ierr = 0; + + Z nutysu = 1; // 1: il existe un fonction areteideale_() + // Z nutysu=0; // 0: on utilise aretmx + R aretmx = _edgeLength; // longueur max aretes future triangulation + //SCRUTE(aretmx); + + nblf = NumberOfWires(F); + //SCRUTE(nblf); + + nudslf = new Z[1 + nblf]; + nudslf[0] = 0; + int iw = 1; + int nbpnt = 0; + + const TopoDS_Wire OW1 = BRepTools::OuterWire(F); + nbpnt += NumberOfPoints(aMesh, OW1); + nudslf[iw++] = nbpnt; + //SCRUTE(nbpnt); + + for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) + { + const TopoDS_Wire & W = TopoDS::Wire(exp.Current()); + if (!OW1.IsSame(W)) + { + nbpnt += NumberOfPoints(aMesh, W); + nudslf[iw++] = nbpnt; + //SCRUTE(nbpnt); + } + } + + uvslf = new R2[nudslf[nblf]]; + //SCRUTE(nudslf[nblf]); + int m = 0; + + map mefistoToDS; // correspondence mefisto index--> points IDNodes + TopoDS_Wire OW = BRepTools::OuterWire(F); + LoadPoints(aMesh, F, OW, uvslf, m, mefistoToDS); + //SCRUTE(m); + + for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) + { + const TopoDS_Wire & W = TopoDS::Wire(exp.Current()); + if (!OW.IsSame(W)) + { + LoadPoints(aMesh, F, W, uvslf, m, mefistoToDS); + //SCRUTE(m); + } + } +// SCRUTE(nudslf[nblf]); +// for (int i=0; i<=nblf; i++) +// { +// MESSAGE(" -+- " <&mefistoToDS) +{ + MESSAGE("StdMeshers_MEFISTO_2D::LoadPoints"); + + SMDS_Mesh * meshDS = aMesh.GetMeshDS(); + + double scalex; + double scaley; + TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD)); + ComputeScaleOnFace(aMesh, F, scalex, scaley); + + TopoDS_Wire W = TopoDS::Wire(WW.Oriented(TopAbs_FORWARD)); + BRepTools_WireExplorer wexp(W, F); + for (wexp.Init(W, F); wexp.More(); wexp.Next()) + { + const TopoDS_Edge & E = wexp.Current(); + + // --- IDNodes of first and last Vertex + + TopoDS_Vertex VFirst, VLast; + TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l + + ASSERT(!VFirst.IsNull()); + SMDS_NodeIteratorPtr lid= + aMesh.GetSubMesh(VFirst)->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode* idFirst = lid->next(); + + ASSERT(!VLast.IsNull()); + lid=aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode* idLast = lid->next(); + + // --- edge internal IDNodes (relies on good order storage, not checked) + + int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); + //SCRUTE(nbPoints); + + double f, l; + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l); + + SMDS_NodeIteratorPtr ite= aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes(); + + bool isForward = (E.Orientation() == TopAbs_FORWARD); + map params; + + while(ite->more()) + { + const SMDS_MeshNode * node = ite->next(); + const SMDS_EdgePosition* epos = + static_cast(node->GetPosition().get()); + double param = epos->GetUParameter(); + params[param] = node; + } + // --- load 2D values into MEFISTO structure, + // add IDNodes in mefistoToDS map + + if (E.Orientation() == TopAbs_FORWARD) + { + gp_Pnt2d p = C2d->Value(f); // first point = Vertex Forward + uvslf[m].x = scalex * p.X(); + uvslf[m].y = scaley * p.Y(); + mefistoToDS[m + 1] = idFirst; + //MESSAGE(" "<::iterator itp = params.begin(); + for (int i = 1; i <= nbPoints; i++) // nbPoints internal + { + double param = (*itp).first; + gp_Pnt2d p = C2d->Value(param); + uvslf[m].x = scalex * p.X(); + uvslf[m].y = scaley * p.Y(); + mefistoToDS[m + 1] = (*itp).second; +// MESSAGE(" "<Value(l); // last point = Vertex Reversed + uvslf[m].x = scalex * p.X(); + uvslf[m].y = scaley * p.Y(); + mefistoToDS[m + 1] = idLast; +// MESSAGE(" "<::reverse_iterator itp = params.rbegin(); + for (int i = nbPoints; i >= 1; i--) + { + double param = (*itp).first; + gp_Pnt2d p = C2d->Value(param); + uvslf[m].x = scalex * p.X(); + uvslf[m].y = scaley * p.Y(); + mefistoToDS[m + 1] = (*itp).second; +// MESSAGE(" "<Value(param); + if (p.X() < xmin) + xmin = p.X(); + if (p.X() > xmax) + xmax = p.X(); + if (p.Y() < ymin) + ymin = p.Y(); + if (p.Y() > ymax) + ymax = p.Y(); +// MESSAGE(" "<< f<<" "<Value(xmin, ymoy); + gp_Pnt PY0 = S->Value(xmoy, ymin); + for (int i = 1; i <= nbp; i++) + { + double x = xmin + (double (i) / double (nbp))*(xmax - xmin); + gp_Pnt PX = S->Value(x, ymoy); + double y = ymin + (double (i) / double (nbp))*(ymax - ymin); + gp_Pnt PY = S->Value(xmoy, y); + length_x += PX.Distance(PX0); + length_y += PY.Distance(PY0); + PX0.SetCoord(PX.X(), PX.Y(), PX.Z()); + PY0.SetCoord(PY.X(), PY.Y(), PY.Z()); + } +// SCRUTE(length_x); +// SCRUTE(length_y); + scalex = length_x / (xmax - xmin); + scaley = length_y / (ymax - ymin); +// SCRUTE(scalex); +// SCRUTE(scaley); + ASSERT(scalex); + ASSERT(scaley); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +void StdMeshers_MEFISTO_2D::StoreResult(SMESH_Mesh & aMesh, + Z nbst, R2 * uvst, Z nbt, Z * nust, + const TopoDS_Face & F, bool faceIsForward, + map&mefistoToDS) +{ + double scalex; + double scaley; + ComputeScaleOnFace(aMesh, F, scalex, scaley); + + SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + + Z n, m; + Handle(Geom_Surface) S = BRep_Tool::Surface(F); + + for (n = 0; n < nbst; n++) + { + double u = uvst[n][0] / scalex; + double v = uvst[n][1] / scaley; + gp_Pnt P = S->Value(u, v); + + if (mefistoToDS.find(n + 1) == mefistoToDS.end()) + { + SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(node, F); + + //MESSAGE(nodeId<<" "<(node->GetPosition().get()); + fpos->SetUParameter(u); + fpos->SetVParameter(v); + } + } + + m = 0; + int mt = 0; + + //SCRUTE(faceIsForward); + for (n = 1; n <= nbt; n++) + { + int inode1 = nust[m++]; + int inode2 = nust[m++]; + int inode3 = nust[m++]; + + const SMDS_MeshNode *n1, *n2, *n3; + n1 = mefistoToDS[inode1]; + n2 = mefistoToDS[inode2]; + n3 = mefistoToDS[inode3]; + //MESSAGE("-- "<AddFace(n1, n2, n3); + else + elt = meshDS->AddFace(n1, n3, n2); + + meshDS->SetMeshElementOnShape(elt, F); + m++; + } +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +double StdMeshers_MEFISTO_2D::ComputeEdgeElementLength(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape) +{ + MESSAGE("StdMeshers_MEFISTO_2D::ComputeEdgeElementLength"); + // **** a mettre dans SMESH_2D_Algo ? + + const TopoDS_Face & FF = TopoDS::Face(aShape); + bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD); + TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD)); + + double meanElementLength = 100; + double wireLength = 0; + int wireElementsNumber = 0; + for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) + { + const TopoDS_Wire & W = TopoDS::Wire(exp.Current()); + for (TopExp_Explorer expe(W, TopAbs_EDGE); expe.More(); expe.Next()) + { + const TopoDS_Edge & E = TopoDS::Edge(expe.Current()); + int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); + double length = EdgeLength(E); + wireLength += length; + wireElementsNumber += nb; + } + } + if (wireElementsNumber) + meanElementLength = wireLength / wireElementsNumber; + //SCRUTE(meanElementLength); + return meanElementLength; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & StdMeshers_MEFISTO_2D::SaveTo(ostream & save) +{ + return save; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & StdMeshers_MEFISTO_2D::LoadFrom(istream & load) +{ + return load; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & operator <<(ostream & save, StdMeshers_MEFISTO_2D & hyp) +{ + return hyp.SaveTo( save ); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & operator >>(istream & load, StdMeshers_MEFISTO_2D & hyp) +{ + return hyp.LoadFrom( load ); +} diff --git a/src/StdMeshers/StdMeshers_MEFISTO_2D.hxx b/src/StdMeshers/StdMeshers_MEFISTO_2D.hxx new file mode 100644 index 000000000..38753d6bd --- /dev/null +++ b/src/StdMeshers/StdMeshers_MEFISTO_2D.hxx @@ -0,0 +1,88 @@ +// SMESH SMESH : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_MEFISTO_2D.hxx +// Moved here from SMESH_MEFISTO_2D.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#ifndef _StdMeshers_MEFISTO_2D_HXX_ +#define _StdMeshers_MEFISTO_2D_HXX_ + +#include "SMESH_2D_Algo.hxx" +#include "StdMeshers_MaxElementArea.hxx" +#include "StdMeshers_LengthFromEdges.hxx" +#include "Rn.h" + +class SMDS_MeshNode; +#include +#include + +class StdMeshers_MEFISTO_2D: + public SMESH_2D_Algo +{ +public: + StdMeshers_MEFISTO_2D(int hypId, int studyId, SMESH_Gen* gen); + virtual ~StdMeshers_MEFISTO_2D(); + + virtual bool CheckHypothesis(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus); + + virtual bool Compute(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape); + + double ComputeEdgeElementLength(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape); + + void LoadPoints(SMESH_Mesh& aMesh, + const TopoDS_Face& F, + const TopoDS_Wire& W, + R2* uvslf, + int& m, + map& mefistoToDS); + + void ComputeScaleOnFace(SMESH_Mesh& aMesh, + const TopoDS_Face& aFace, + double& scalex, + double& scaley); + + void StoreResult (SMESH_Mesh& aMesh, + Z nbst, R2* uvst, Z nbt, Z* nust, + const TopoDS_Face& F, bool faceIsForward, + map& mefistoToDS); + + ostream & SaveTo(ostream & save); + istream & LoadFrom(istream & load); + friend ostream & operator << (ostream & save, StdMeshers_MEFISTO_2D & hyp); + friend istream & operator >> (istream & load, StdMeshers_MEFISTO_2D & hyp); + +protected: + double _edgeLength; + double _maxElementArea; + const StdMeshers_MaxElementArea* _hypMaxElementArea; + const StdMeshers_LengthFromEdges* _hypLengthFromEdges; +}; + +#endif diff --git a/src/StdMeshers/StdMeshers_MaxElementArea.cxx b/src/StdMeshers/StdMeshers_MaxElementArea.cxx new file mode 100644 index 000000000..c4a2d5e17 --- /dev/null +++ b/src/StdMeshers/StdMeshers_MaxElementArea.cxx @@ -0,0 +1,139 @@ +// SMESH SMESH : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_MaxElementArea.cxx +// Moved here from SMESH_MaxElementArea.cxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +using namespace std; +#include "StdMeshers_MaxElementArea.hxx" +#include "utilities.h" + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_MaxElementArea::StdMeshers_MaxElementArea(int hypId, int studyId, SMESH_Gen* gen) + : SMESH_Hypothesis(hypId, studyId, gen) +{ + _maxArea =1.; + _name = "MaxElementArea"; +// SCRUTE(_name); +// SCRUTE(&_name); + _param_algo_dim = 2; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_MaxElementArea::~StdMeshers_MaxElementArea() +{ +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +void StdMeshers_MaxElementArea::SetMaxArea(double maxArea) + throw (SALOME_Exception) +{ + double oldArea = _maxArea; + if (maxArea <= 0) + throw SALOME_Exception(LOCALIZED("maxArea must be positive")); + _maxArea = maxArea; + if (_maxArea != oldArea) + NotifySubMeshesHypothesisModification(); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +double StdMeshers_MaxElementArea::GetMaxArea() const +{ + return _maxArea; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & StdMeshers_MaxElementArea::SaveTo(ostream & save) +{ + save << this->_maxArea; + return save; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & StdMeshers_MaxElementArea::LoadFrom(istream & load) +{ + bool isOK = true; + double a; + isOK = (load >> a); + if (isOK) + this->_maxArea = a; + else + load.clear(ios::badbit | load.rdstate()); + return load; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & operator << (ostream & save, StdMeshers_MaxElementArea & hyp) +{ + return hyp.SaveTo( save ); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & operator >> (istream & load, StdMeshers_MaxElementArea & hyp) +{ + return hyp.LoadFrom( load ); +} + diff --git a/src/StdMeshers/StdMeshers_MaxElementArea.hxx b/src/StdMeshers/StdMeshers_MaxElementArea.hxx new file mode 100644 index 000000000..52af887c8 --- /dev/null +++ b/src/StdMeshers/StdMeshers_MaxElementArea.hxx @@ -0,0 +1,55 @@ +// SMESH SMESH : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_MaxElementArea.hxx +// Moved here from SMESH_MaxElementArea.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#ifndef _SMESH_MAXELEMENTAREA_HXX_ +#define _SMESH_MAXELEMENTAREA_HXX_ + +#include "SMESH_Hypothesis.hxx" +#include "Utils_SALOME_Exception.hxx" + +class StdMeshers_MaxElementArea:public SMESH_Hypothesis +{ + public: + StdMeshers_MaxElementArea(int hypId, int studyId, SMESH_Gen * gen); + virtual ~ StdMeshers_MaxElementArea(); + + void SetMaxArea(double maxArea) throw(SALOME_Exception); + + double GetMaxArea() const; + + virtual ostream & SaveTo(ostream & save); + virtual istream & LoadFrom(istream & load); + friend ostream & operator <<(ostream & save, StdMeshers_MaxElementArea & hyp); + friend istream & operator >>(istream & load, StdMeshers_MaxElementArea & hyp); + + protected: + double _maxArea; +}; + +#endif diff --git a/src/StdMeshers/StdMeshers_MaxElementVolume.cxx b/src/StdMeshers/StdMeshers_MaxElementVolume.cxx new file mode 100644 index 000000000..f9f6b6322 --- /dev/null +++ b/src/StdMeshers/StdMeshers_MaxElementVolume.cxx @@ -0,0 +1,141 @@ +// SMESH SMESH : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_MaxElementVolume.cxx +// Moved here from SMESH_MaxElementVolume.cxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +using namespace std; + +#include "StdMeshers_MaxElementVolume.hxx" +#include "utilities.h" + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_MaxElementVolume::StdMeshers_MaxElementVolume(int hypId, int studyId, SMESH_Gen* gen) + : SMESH_Hypothesis(hypId, studyId, gen) +{ + _maxVolume =1.; + _name = "MaxElementVolume"; +// SCRUTE(_name); + SCRUTE(&_name); + _param_algo_dim = 3; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_MaxElementVolume::~StdMeshers_MaxElementVolume() +{ + MESSAGE("StdMeshers_MaxElementVolume::~StdMeshers_MaxElementVolume"); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +void StdMeshers_MaxElementVolume::SetMaxVolume(double maxVolume) + throw (SALOME_Exception) +{ + double oldVolume = _maxVolume; + if (maxVolume <= 0) + throw SALOME_Exception(LOCALIZED("maxVolume must be positive")); + _maxVolume = maxVolume; + if (_maxVolume != oldVolume) + NotifySubMeshesHypothesisModification(); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +double StdMeshers_MaxElementVolume::GetMaxVolume() const +{ + return _maxVolume; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & StdMeshers_MaxElementVolume::SaveTo(ostream & save) +{ + save << this->_maxVolume; + return save; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & StdMeshers_MaxElementVolume::LoadFrom(istream & load) +{ + bool isOK = true; + double a; + isOK = (load >> a); + if (isOK) + this->_maxVolume = a; + else + load.clear(ios::badbit | load.rdstate()); + return load; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & operator << (ostream & save, StdMeshers_MaxElementVolume & hyp) +{ + return hyp.SaveTo( save ); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & operator >> (istream & load, StdMeshers_MaxElementVolume & hyp) +{ + return hyp.LoadFrom( load ); +} + diff --git a/src/StdMeshers/StdMeshers_MaxElementVolume.hxx b/src/StdMeshers/StdMeshers_MaxElementVolume.hxx new file mode 100644 index 000000000..ee9986f1f --- /dev/null +++ b/src/StdMeshers/StdMeshers_MaxElementVolume.hxx @@ -0,0 +1,57 @@ +// SMESH SMESH : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_MaxElementVolume.hxx +// Moved here from SMESH_MaxElementVolume.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#ifndef _SMESH_MAXELEMENTVOLUME_HXX_ +#define _SMESH_MAXELEMENTVOLUME_HXX_ + +#include "SMESH_Hypothesis.hxx" +#include "Utils_SALOME_Exception.hxx" + +class StdMeshers_MaxElementVolume: + public SMESH_Hypothesis +{ +public: + StdMeshers_MaxElementVolume(int hypId, int studyId, SMESH_Gen* gen); + virtual ~StdMeshers_MaxElementVolume(); + + void SetMaxVolume(double maxVolume) + throw (SALOME_Exception); + + double GetMaxVolume() const; + + virtual ostream & SaveTo(ostream & save); + virtual istream & LoadFrom(istream & load); + friend ostream & operator << (ostream & save, StdMeshers_MaxElementVolume & hyp); + friend istream & operator >> (istream & load, StdMeshers_MaxElementVolume & hyp); + +protected: + double _maxVolume; +}; + +#endif diff --git a/src/SMESH_I/SMESH_MaxElementArea_i.cxx b/src/StdMeshers/StdMeshers_NotConformAllowed.cxx similarity index 61% rename from src/SMESH_I/SMESH_MaxElementArea_i.cxx rename to src/StdMeshers/StdMeshers_NotConformAllowed.cxx index 2f557c3d4..5c471b2a0 100644 --- a/src/SMESH_I/SMESH_MaxElementArea_i.cxx +++ b/src/StdMeshers/StdMeshers_NotConformAllowed.cxx @@ -1,4 +1,4 @@ -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// SMESH StdMeshers : implementaion of SMESH idl descriptions // // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -21,36 +21,36 @@ // // // -// File : SMESH_MaxElementArea_i.cxx +// File : StdMeshers_NotConformAllowed.cxx // Author : Paul RASCLE, EDF // Module : SMESH // $Header$ using namespace std; -using namespace std; -#include "SMESH_MaxElementArea_i.hxx" -#include "SMESH_Gen.hxx" -#include "SMESH_HypothesisFactory.hxx" - -#include "Utils_CorbaException.hxx" +#include "StdMeshers_NotConformAllowed.hxx" #include "utilities.h" //============================================================================= /*! - * Constructor: - * _name is related to the class name: prefix = SMESH_ ; suffix = _i . + * + */ +//============================================================================= + +StdMeshers_NotConformAllowed::StdMeshers_NotConformAllowed(int hypId, int studyId, SMESH_Gen* gen) + : SMESH_Hypothesis(hypId, studyId, gen) +{ + _name = "NotConformAllowed"; + _param_algo_dim = -1; +} + +//============================================================================= +/*! + * */ //============================================================================= -SMESH_MaxElementArea_i::SMESH_MaxElementArea_i(const char* anHyp, - int studyId, - ::SMESH_Gen* genImpl) +StdMeshers_NotConformAllowed::~StdMeshers_NotConformAllowed() { - MESSAGE("SMESH_MaxElementArea_i::SMESH_MaxElementArea_i"); - _impl = new ::SMESH_MaxElementArea(genImpl->_hypothesisFactory.GetANewId(), - studyId, - genImpl); - _baseImpl = _impl; } //============================================================================= @@ -59,8 +59,9 @@ SMESH_MaxElementArea_i::SMESH_MaxElementArea_i(const char* anHyp, */ //============================================================================= -SMESH_MaxElementArea_i::~SMESH_MaxElementArea_i() +ostream & StdMeshers_NotConformAllowed::SaveTo(ostream & save) { + return save << this; } //============================================================================= @@ -69,19 +70,9 @@ SMESH_MaxElementArea_i::~SMESH_MaxElementArea_i() */ //============================================================================= -void SMESH_MaxElementArea_i::SetMaxElementArea(CORBA::Double area) - throw (SALOME::SALOME_Exception) +istream & StdMeshers_NotConformAllowed::LoadFrom(istream & load) { - ASSERT(_impl); - try - { - _impl->SetMaxArea(area); - } - catch (SALOME_Exception& S_ex) - { - THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), \ - SALOME::BAD_PARAM); - } + return load >> (*this); } //============================================================================= @@ -90,9 +81,18 @@ void SMESH_MaxElementArea_i::SetMaxElementArea(CORBA::Double area) */ //============================================================================= -CORBA::Double SMESH_MaxElementArea_i::GetMaxElementArea() +ostream & operator << (ostream & save, StdMeshers_NotConformAllowed & hyp) { - ASSERT(_impl); - return _impl->GetMaxArea(); + return save; } +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & operator >> (istream & load, StdMeshers_NotConformAllowed & hyp) +{ + return load; +} diff --git a/src/StdMeshers/StdMeshers_NotConformAllowed.hxx b/src/StdMeshers/StdMeshers_NotConformAllowed.hxx new file mode 100644 index 000000000..079742458 --- /dev/null +++ b/src/StdMeshers/StdMeshers_NotConformAllowed.hxx @@ -0,0 +1,48 @@ +// SMESH StdMeshers : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_NotConformAllowed.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#ifndef _StdMeshers_NotConformAllowed_HXX_ +#define _StdMeshers_NotConformAllowed_HXX_ + +#include "SMESH_Hypothesis.hxx" +#include "Utils_SALOME_Exception.hxx" + +class StdMeshers_NotConformAllowed: + public SMESH_Hypothesis +{ +public: + StdMeshers_NotConformAllowed(int hypId, int studyId, SMESH_Gen* gen); + virtual ~StdMeshers_NotConformAllowed(); + + virtual ostream & SaveTo(ostream & save); + virtual istream & LoadFrom(istream & load); + friend ostream & operator << (ostream & save, StdMeshers_NotConformAllowed & hyp); + friend istream & operator >> (istream & load, StdMeshers_NotConformAllowed & hyp); +}; + +#endif diff --git a/src/StdMeshers/StdMeshers_NumberOfSegments.cxx b/src/StdMeshers/StdMeshers_NumberOfSegments.cxx new file mode 100644 index 000000000..c16c1373b --- /dev/null +++ b/src/StdMeshers/StdMeshers_NumberOfSegments.cxx @@ -0,0 +1,171 @@ +// SMESH SMESH : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_NumberOfSegments.cxx +// Moved here from SMESH_NumberOfSegments.cxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +using namespace std; +#include "StdMeshers_NumberOfSegments.hxx" + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_NumberOfSegments::StdMeshers_NumberOfSegments(int hypId, int studyId, + SMESH_Gen * gen):SMESH_Hypothesis(hypId, studyId, gen) +{ + _numberOfSegments = 1; + _scaleFactor = 1.0; + _name = "NumberOfSegments"; + _param_algo_dim = 1; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_NumberOfSegments::~StdMeshers_NumberOfSegments() +{ +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +void StdMeshers_NumberOfSegments::SetNumberOfSegments(int segmentsNumber) +throw(SALOME_Exception) +{ + int oldNumberOfSegments = _numberOfSegments; + if (segmentsNumber <= 0) + throw + SALOME_Exception(LOCALIZED("number of segments must be positive")); + _numberOfSegments = segmentsNumber; + + if (oldNumberOfSegments != _numberOfSegments) + NotifySubMeshesHypothesisModification(); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +int StdMeshers_NumberOfSegments::GetNumberOfSegments() const +{ + return _numberOfSegments; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +void StdMeshers_NumberOfSegments::SetScaleFactor(double scaleFactor) +throw(SALOME_Exception) +{ + if (scaleFactor < 0) + throw SALOME_Exception(LOCALIZED("scale factor must be positive")); + _scaleFactor = scaleFactor; + + NotifySubMeshesHypothesisModification(); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +double StdMeshers_NumberOfSegments::GetScaleFactor() const +{ + return _scaleFactor; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & StdMeshers_NumberOfSegments::SaveTo(ostream & save) +{ + save << this->_numberOfSegments << " " << this->_scaleFactor; + return save; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & StdMeshers_NumberOfSegments::LoadFrom(istream & load) +{ + bool isOK = true; + int a; + isOK = (load >> a); + if (isOK) + this->_numberOfSegments = a; + else + load.clear(ios::badbit | load.rdstate()); + double b; + isOK = (load >> b); + if (isOK) + this->_scaleFactor = b; + else + load.clear(ios::badbit | load.rdstate()); + return load; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & operator <<(ostream & save, StdMeshers_NumberOfSegments & hyp) +{ + return hyp.SaveTo( save ); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & operator >>(istream & load, StdMeshers_NumberOfSegments & hyp) +{ + return hyp.LoadFrom( load ); +} diff --git a/src/StdMeshers/StdMeshers_NumberOfSegments.hxx b/src/StdMeshers/StdMeshers_NumberOfSegments.hxx new file mode 100644 index 000000000..79147e1a2 --- /dev/null +++ b/src/StdMeshers/StdMeshers_NumberOfSegments.hxx @@ -0,0 +1,63 @@ +// SMESH SMESH : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_NumberOfSegments.hxx +// Moved here from SMESH_NumberOfSegments.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#ifndef _SMESH_NUMBEROFSEGMENTS_HXX_ +#define _SMESH_NUMBEROFSEGMENTS_HXX_ + +#include "SMESH_Hypothesis.hxx" +#include "Utils_SALOME_Exception.hxx" + +class StdMeshers_NumberOfSegments: + public SMESH_Hypothesis +{ +public: + StdMeshers_NumberOfSegments(int hypId, int studyId, SMESH_Gen* gen); + virtual ~StdMeshers_NumberOfSegments(); + + void SetNumberOfSegments(int segmentsNumber) + throw (SALOME_Exception); + + int GetNumberOfSegments() const; + + void SetScaleFactor(double scaleFactor) + throw (SALOME_Exception); + + double GetScaleFactor() const; + + virtual ostream & SaveTo(ostream & save); + virtual istream & LoadFrom(istream & load); + friend ostream& operator << (ostream & save, StdMeshers_NumberOfSegments & hyp); + friend istream& operator >> (istream & load, StdMeshers_NumberOfSegments & hyp); + +protected: + int _numberOfSegments; + double _scaleFactor; +}; + +#endif diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx new file mode 100644 index 000000000..14815906d --- /dev/null +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx @@ -0,0 +1,644 @@ +// SMESH SMESH : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_Quadrangle_2D.cxx +// Moved here from SMESH_Quadrangle_2D.cxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +using namespace std; +#include "StdMeshers_Quadrangle_2D.hxx" +#include "SMESH_Gen.hxx" +#include "SMESH_Mesh.hxx" + +#include "SMDS_MeshElement.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_EdgePosition.hxx" +#include "SMDS_FacePosition.hxx" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utilities.h" +#include "Utils_ExceptHandlers.hxx" + + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D(int hypId, + int studyId, SMESH_Gen * gen):SMESH_2D_Algo(hypId, studyId, gen) +{ + MESSAGE("StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D"); + _name = "Quadrangle_2D"; + // _shapeType = TopAbs_FACE; + _shapeType = (1 << TopAbs_FACE); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_Quadrangle_2D::~StdMeshers_Quadrangle_2D() +{ + MESSAGE("StdMeshers_Quadrangle_2D::~StdMeshers_Quadrangle_2D"); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool StdMeshers_Quadrangle_2D::CheckHypothesis + (SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus) +{ + //MESSAGE("StdMeshers_Quadrangle_2D::CheckHypothesis"); + + bool isOk = true; + aStatus = SMESH_Hypothesis::HYP_OK; + + // nothing to check + + return isOk; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool StdMeshers_Quadrangle_2D::Compute(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape)throw(SALOME_Exception) +{ + Unexpect aCatch(SalomeException); + //MESSAGE("StdMeshers_Quadrangle_2D::Compute"); + SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape); + + FaceQuadStruct *quad = CheckAnd2Dcompute(aMesh, aShape); + if (!quad) + return false; + + // --- compute 3D values on points, store points & quadrangles + + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; + int nbVertices = nbdown * nbright; + int nbQuad = (nbdown - 1) * (nbright - 1); + //SCRUTE(nbVertices); + //SCRUTE(nbQuad); + + // const TopoDS_Face& FF = TopoDS::Face(aShape); + // bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD); + // TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD)); + const TopoDS_Face & F = TopoDS::Face(aShape); + bool faceIsForward = (F.Orientation() == TopAbs_FORWARD); + Handle(Geom_Surface) S = BRep_Tool::Surface(F); + + for (int i = 1; i < nbdown - 1; i++) + for (int j = 1; j < nbright - 1; j++) // internal points + { + int ij = j * nbdown + i; + double u = quad->uv_grid[ij].u; + double v = quad->uv_grid[ij].v; + gp_Pnt P = S->Value(u, v); + SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(node, F); + quad->uv_grid[ij].node = node; +// Handle (SMDS_FacePosition) fpos +// = new SMDS_FacePosition(theSubMesh->GetId(),i,j); // easier than u,v +// node->SetPosition(fpos); + SMDS_FacePosition* fpos = + dynamic_cast(node->GetPosition().get()); + fpos->SetUParameter(i); + fpos->SetVParameter(j); + } + + // bool isQuadForward = ( faceIsForward == quad->isEdgeForward[0]); + for (int i = 0; i < nbdown - 1; i++) + for (int j = 0; j < nbright - 1; j++) // faces + { + const SMDS_MeshNode *a, *b, *c, *d; + a = quad->uv_grid[j * nbdown + i].node; + b = quad->uv_grid[j * nbdown + i + 1].node; + c = quad->uv_grid[(j + 1) * nbdown + i + 1].node; + d = quad->uv_grid[(j + 1) * nbdown + i].node; + // if (isQuadForward) faceId = meshDS->AddFace(a,b,c,d); + // else faceId = meshDS->AddFace(a,d,c,b); + SMDS_MeshFace * face = meshDS->AddFace(a, b, c, d); + meshDS->SetMeshElementOnShape(face, F); + } + + QuadDelete(quad); + bool isOk = true; + return isOk; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +FaceQuadStruct *StdMeshers_Quadrangle_2D::CheckAnd2Dcompute(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape)throw(SALOME_Exception) +{ + Unexpect aCatch(SalomeException); + //MESSAGE("StdMeshers_Quadrangle_2D::ComputeWithoutStore"); + + SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape); + + // const TopoDS_Face& FF = TopoDS::Face(aShape); + // bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD); + // TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD)); + const TopoDS_Face & F = TopoDS::Face(aShape); + bool faceIsForward = (F.Orientation() == TopAbs_FORWARD); + + // verify 1 wire only, with 4 edges, same number of points on opposite edges + + if (NumberOfWires(F) != 1) + { + MESSAGE("only 1 wire by face (quadrangles)"); + return 0; + //throw SALOME_Exception(LOCALIZED("only 1 wire by face (quadrangles)")); + } + // const TopoDS_Wire WW = BRepTools::OuterWire(F); + // TopoDS_Wire W = TopoDS::Wire(WW.Oriented(TopAbs_FORWARD)); + const TopoDS_Wire & W = BRepTools::OuterWire(F); + BRepTools_WireExplorer wexp(W, F); + + FaceQuadStruct *quad = new FaceQuadStruct; + for (int i = 0; i < 4; i++) + quad->uv_edges[i] = 0; + quad->uv_grid = 0; + + int nbEdges = 0; + for (wexp.Init(W, F); wexp.More(); wexp.Next()) + { + // const TopoDS_Edge& EE = wexp.Current(); + // TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD)); + const TopoDS_Edge & E = wexp.Current(); + int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); + if (nbEdges < 4) + { + quad->edge[nbEdges] = E; + quad->nbPts[nbEdges] = nb + 2; // internal points + 2 extrema + } + nbEdges++; + } + + if (nbEdges != 4) + { + MESSAGE("face must have 4 edges /quadrangles"); + QuadDelete(quad); + return 0; + //throw SALOME_Exception(LOCALIZED("face must have 4 edges /quadrangles")); + } + + if (quad->nbPts[0] != quad->nbPts[2]) + { + MESSAGE("different point number-opposed edge"); + QuadDelete(quad); + return 0; + //throw SALOME_Exception(LOCALIZED("different point number-opposed edge")); + } + + if (quad->nbPts[1] != quad->nbPts[3]) + { + MESSAGE("different point number-opposed edge"); + QuadDelete(quad); + return 0; + //throw SALOME_Exception(LOCALIZED("different point number-opposed edge")); + } + + // set normalized grid on unit square in parametric domain + + SetNormalizedGrid(aMesh, F, quad); + + return quad; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +void StdMeshers_Quadrangle_2D::QuadDelete(FaceQuadStruct * quad) +{ + //MESSAGE("StdMeshers_Quadrangle_2D::QuadDelete"); + if (quad) + { + for (int i = 0; i < 4; i++) + { + if (quad->uv_edges[i]) + delete[]quad->uv_edges[i]; + quad->edge[i].Nullify(); + } + if (quad->uv_grid) + delete[]quad->uv_grid; + delete quad; + } +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +void StdMeshers_Quadrangle_2D::SetNormalizedGrid(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, FaceQuadStruct * quad) throw(SALOME_Exception) +{ + Unexpect aCatch(SalomeException); + // Algorithme décrit dans "Génération automatique de maillages" + // P.L. GEORGE, MASSON, § 6.4.1 p. 84-85 + // traitement dans le domaine paramétrique 2d u,v + // transport - projection sur le carré unité + + const TopoDS_Face & F = TopoDS::Face(aShape); + + // 1 --- find orientation of the 4 edges, by test on extrema + + // max min 0 x1 1 + // |<----north-2-------^ a3 -------------> a2 + // | | ^1 1^ + // west-3 east-1 =right | | + // | | ==> | | + // y0 | | y1 | | + // | | |0 0| + // v----south-0--------> a0 -------------> a1 + // min max 0 x0 1 + // =down + // + + Handle(Geom2d_Curve) c2d[4]; + gp_Pnt2d pf[4]; + gp_Pnt2d pl[4]; + for (int i = 0; i < 4; i++) + { + c2d[i] = BRep_Tool::CurveOnSurface(quad->edge[i], + F, quad->first[i], quad->last[i]); + pf[i] = c2d[i]->Value(quad->first[i]); + pl[i] = c2d[i]->Value(quad->last[i]); + quad->isEdgeForward[i] = false; + } + + double eps2d = 1.e-3; // *** utiliser plutot TopExp::CommonVertex, puis + // distances si piece fausse + int i = 0; + if ((pf[1].Distance(pl[0]) < eps2d) || (pl[1].Distance(pl[0]) < eps2d)) + { + quad->isEdgeForward[0] = true; + } + else + { + double tmp = quad->first[0]; + quad->first[0] = quad->last[0]; + quad->last[0] = tmp; + pf[0] = c2d[0]->Value(quad->first[0]); + pl[0] = c2d[0]->Value(quad->last[0]); + } + for (int i = 1; i < 4; i++) + { + quad->isEdgeForward[i] = (pf[i].Distance(pl[i - 1]) < eps2d); + if (!quad->isEdgeForward[i]) + { + double tmp = quad->first[i]; + quad->first[i] = quad->last[i]; + quad->last[i] = tmp; + pf[i] = c2d[i]->Value(quad->first[i]); + pl[i] = c2d[i]->Value(quad->last[i]); + //SCRUTE(pf[i].Distance(pl[i-1])); + ASSERT(pf[i].Distance(pl[i - 1]) < eps2d); + } + } + //SCRUTE(pf[0].Distance(pl[3])); + ASSERT(pf[0].Distance(pl[3]) < eps2d); + +// for (int i=0; i<4; i++) +// { +// SCRUTE(quad->isEdgeForward[i]); +// MESSAGE(" -first "<uv_edges[i] = LoadEdgePoints(aMesh, F, + quad->edge[i], quad->first[i], quad->last[i]); + + // quad->isEdgeForward[i]); + } + for (int i = 2; i < 4; i++) + { + quad->uv_edges[i] = LoadEdgePoints(aMesh, F, + quad->edge[i], quad->last[i], quad->first[i]); + + // !quad->isEdgeForward[i]); + } + + // 3 --- 2D normalized values on unit square [0..1][0..1] + + int nbdown = quad->nbPts[0]; + int nbright = quad->nbPts[1]; + quad->uv_grid = new UVPtStruct[nbright * nbdown]; + + UVPtStruct *uv_grid = quad->uv_grid; + UVPtStruct *uv_e0 = quad->uv_edges[0]; + UVPtStruct *uv_e1 = quad->uv_edges[1]; + UVPtStruct *uv_e2 = quad->uv_edges[2]; + UVPtStruct *uv_e3 = quad->uv_edges[3]; + gp_Pnt2d a0 = pf[0]; + gp_Pnt2d a1 = pf[1]; + gp_Pnt2d a2 = pf[2]; + gp_Pnt2d a3 = pf[3]; + + // nodes Id on edges + + int j = 0; + for (int i = 0; i < nbdown; i++) + { + int ij = j * nbdown + i; + uv_grid[ij].node = uv_e0[i].node; + } + i = nbdown - 1; + for (int j = 0; j < nbright; j++) + { + int ij = j * nbdown + i; + uv_grid[ij].node = uv_e1[j].node; + } + j = nbright - 1; + for (int i = 0; i < nbdown; i++) + { + int ij = j * nbdown + i; + uv_grid[ij].node = uv_e2[i].node; + } + i = 0; + for (int j = 0; j < nbright; j++) + { + int ij = j * nbdown + i; + uv_grid[ij].node = uv_e3[j].node; + } + + // normalized 2d values on grid + + for (int i = 0; i < nbdown; i++) + for (int j = 0; j < nbright; j++) + { + int ij = j * nbdown + i; + // --- droite i cste : x = x0 + y(x1-x0) + double x0 = uv_e0[i].normParam; // bas - sud + double x1 = uv_e2[i].normParam; // haut - nord + // --- droite j cste : y = y0 + x(y1-y0) + double y0 = uv_e3[j].normParam; // gauche-ouest + double y1 = uv_e1[j].normParam; // droite - est + // --- intersection : x=x0+(y0+x(y1-y0))(x1-x0) + double x = (x0 + y0 * (x1 - x0)) / (1 - (y1 - y0) * (x1 - x0)); + double y = y0 + x * (y1 - y0); + uv_grid[ij].x = x; + uv_grid[ij].y = y; + //MESSAGE("-xy-01 "<Value(param_0); + gp_Pnt2d p1 = c2d[1]->Value(param_1); + gp_Pnt2d p2 = c2d[2]->Value(param_2); + gp_Pnt2d p3 = c2d[3]->Value(param_3); + + double u = + (1 - y) * p0.X() + x * p1.X() + y * p2.X() + (1 - x) * p3.X(); + double v = + (1 - y) * p0.Y() + x * p1.Y() + y * p2.Y() + (1 - x) * p3.Y(); + + u -= (1 - x) * (1 - y) * a0.X() + x * (1 - y) * a1.X() + + x * y * a2.X() + (1 - x) * y * a3.X(); + v -= (1 - x) * (1 - y) * a0.Y() + x * (1 - y) * a1.Y() + + x * y * a2.Y() + (1 - x) * y * a3.Y(); + + uv_grid[ij].u = u; + uv_grid[ij].v = v; + + //MESSAGE("-uv- "<GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode * idFirst = lid->next(); + + ASSERT(!VLast.IsNull()); + lid=aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode * idLast = lid->next(); + + // --- edge internal IDNodes (relies on good order storage, not checked) + + int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes(); + //SCRUTE(nbPoints); + UVPtStruct *uvslf = new UVPtStruct[nbPoints + 2]; + + double f, l; + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l); + + map params; + SMDS_NodeIteratorPtr ite= aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes(); + + while(ite->more()) + { + const SMDS_MeshNode * node = ite->next(); + const SMDS_EdgePosition* epos = + static_cast(node->GetPosition().get()); + double param = epos->GetUParameter(); + params[param] = node; + } + + bool isForward = (((l - f) * (last - first)) > 0); + double paramin = 0; + double paramax = 0; + if (isForward) + { + paramin = f; + paramax = l; + gp_Pnt2d p = C2d->Value(f); // first point = Vertex Forward + uvslf[0].x = p.X(); + uvslf[0].y = p.Y(); + uvslf[0].param = f; + uvslf[0].node = idFirst; + //MESSAGE("__ f "<::iterator itp = params.begin(); + for (int i = 1; i <= nbPoints; i++) // nbPoints internal + { + double param = (*itp).first; + gp_Pnt2d p = C2d->Value(param); + uvslf[i].x = p.X(); + uvslf[i].y = p.Y(); + uvslf[i].param = param; + uvslf[i].node = (*itp).second; + //MESSAGE("__ "<Value(l); // last point = Vertex Reversed + uvslf[nbPoints + 1].x = p.X(); + uvslf[nbPoints + 1].y = p.Y(); + uvslf[nbPoints + 1].param = l; + uvslf[nbPoints + 1].node = idLast; + //MESSAGE("__ l "<Value(l); // first point = Vertex Reversed + uvslf[0].x = p.X(); + uvslf[0].y = p.Y(); + uvslf[0].param = l; + uvslf[0].node = idLast; + //MESSAGE("__ l "<::reverse_iterator itp = params.rbegin(); + for (int j = nbPoints; j >= 1; j--) // nbPoints internal + { + double param = (*itp).first; + int i = nbPoints + 1 - j; + gp_Pnt2d p = C2d->Value(param); + uvslf[i].x = p.X(); + uvslf[i].y = p.Y(); + uvslf[i].param = param; + uvslf[i].node = (*itp).second; + //MESSAGE("__ "<Value(f); // last point = Vertex Forward + uvslf[nbPoints + 1].x = p.X(); + uvslf[nbPoints + 1].y = p.Y(); + uvslf[nbPoints + 1].param = f; + uvslf[nbPoints + 1].node = idFirst; + //MESSAGE("__ f "<>(istream & load, StdMeshers_Quadrangle_2D & hyp) +{ + return hyp.LoadFrom( load ); +} diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx new file mode 100644 index 000000000..afa3882f2 --- /dev/null +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx @@ -0,0 +1,102 @@ +// SMESH SMESH : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_Quadrangle_2D.hxx +// Moved here from SMESH_Quadrangle_2D.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#ifndef _SMESH_QUADRANGLE_2D_HXX_ +#define _SMESH_QUADRANGLE_2D_HXX_ + +#include "SMESH_2D_Algo.hxx" +#include "SMESH_Mesh.hxx" +#include "Utils_SALOME_Exception.hxx" + +typedef struct uvPtStruct +{ + double param; + double normParam; + double u; // original 2d parameter + double v; + double x; // 2d parameter, normalized [0,1] + double y; + const SMDS_MeshNode * node; +} UVPtStruct; + +typedef struct faceQuadStruct +{ + int nbPts[4]; + TopoDS_Edge edge[4]; + double first[4]; + double last[4]; + bool isEdgeForward[4]; + UVPtStruct* uv_edges[4]; + UVPtStruct* uv_grid; +} FaceQuadStruct; + +class StdMeshers_Quadrangle_2D: + public SMESH_2D_Algo +{ +public: + StdMeshers_Quadrangle_2D(int hypId, int studyId, SMESH_Gen* gen); + virtual ~StdMeshers_Quadrangle_2D(); + + virtual bool CheckHypothesis(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus); + + virtual bool Compute(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape) + throw (SALOME_Exception); + + FaceQuadStruct* CheckAnd2Dcompute(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape) + throw (SALOME_Exception); + + void QuadDelete(FaceQuadStruct* quad); + + ostream & SaveTo(ostream & save); + istream & LoadFrom(istream & load); + friend ostream & operator << (ostream & save, StdMeshers_Quadrangle_2D & hyp); + friend istream & operator >> (istream & load, StdMeshers_Quadrangle_2D & hyp); + +protected: + + void SetNormalizedGrid(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + FaceQuadStruct* quad) + throw (SALOME_Exception); + + UVPtStruct* LoadEdgePoints(SMESH_Mesh& aMesh, + const TopoDS_Face& F, + const TopoDS_Edge& E, + double first, + double last); +// bool isForward); + +// FaceQuadStruct _quadDesc; +}; + +#endif diff --git a/src/StdMeshers/StdMeshers_Regular_1D.cxx b/src/StdMeshers/StdMeshers_Regular_1D.cxx new file mode 100644 index 000000000..aa069ff8c --- /dev/null +++ b/src/StdMeshers/StdMeshers_Regular_1D.cxx @@ -0,0 +1,331 @@ +// SMESH SMESH : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_Regular_1D.cxx +// Moved here from SMESH_Regular_1D.cxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +using namespace std; + +#include "StdMeshers_Regular_1D.hxx" +#include "SMESH_Gen.hxx" +#include "SMESH_Mesh.hxx" + +#include "StdMeshers_LocalLength.hxx" +#include "StdMeshers_NumberOfSegments.hxx" + +#include "SMDS_MeshElement.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_EdgePosition.hxx" + +#include "utilities.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_Regular_1D::StdMeshers_Regular_1D(int hypId, int studyId, + SMESH_Gen * gen):SMESH_1D_Algo(hypId, studyId, gen) +{ + MESSAGE("StdMeshers_Regular_1D::StdMeshers_Regular_1D"); + _name = "Regular_1D"; + // _shapeType = TopAbs_EDGE; + _shapeType = (1 << TopAbs_EDGE); + _compatibleHypothesis.push_back("LocalLength"); + _compatibleHypothesis.push_back("NumberOfSegments"); + + _localLength = 0; + _numberOfSegments = 0; + _hypLocalLength = NULL; + _hypNumberOfSegments = NULL; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_Regular_1D::~StdMeshers_Regular_1D() +{ +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool StdMeshers_Regular_1D::CheckHypothesis + (SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus) +{ + //MESSAGE("StdMeshers_Regular_1D::CheckHypothesis"); + + list ::const_iterator itl; + const SMESHDS_Hypothesis *theHyp; + + const list &hyps = GetUsedHypothesis(aMesh, aShape); + int nbHyp = hyps.size(); + if (!nbHyp) + { + aStatus = SMESH_Hypothesis::HYP_MISSING; + return false; // can't work with no hypothesis + } + + itl = hyps.begin(); + theHyp = (*itl); // use only the first hypothesis + + string hypName = theHyp->GetName(); + int hypId = theHyp->GetID(); + //SCRUTE(hypName); + + bool isOk = false; + + if (hypName == "LocalLength") + { + _hypLocalLength = dynamic_cast (theHyp); + ASSERT(_hypLocalLength); + _localLength = _hypLocalLength->GetLength(); + _numberOfSegments = 0; + isOk = true; + aStatus = SMESH_Hypothesis::HYP_OK; + } + + else if (hypName == "NumberOfSegments") + { + _hypNumberOfSegments = + dynamic_cast (theHyp); + ASSERT(_hypNumberOfSegments); + _numberOfSegments = _hypNumberOfSegments->GetNumberOfSegments(); + _scaleFactor = _hypNumberOfSegments->GetScaleFactor(); + _localLength = 0; + isOk = true; + aStatus = SMESH_Hypothesis::HYP_OK; + } + else + aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE; + + //SCRUTE(_localLength); + //SCRUTE(_numberOfSegments); + + return isOk; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) +{ + MESSAGE("StdMeshers_Regular_1D::Compute"); + + SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape); + + const TopoDS_Edge & EE = TopoDS::Edge(aShape); + TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD)); + + double f, l; + Handle(Geom_Curve) Curve = BRep_Tool::Curve(E, f, l); + + TopoDS_Vertex VFirst, VLast; + TopExp::Vertices(E, VFirst, VLast); // Vfirst corresponds to f and Vlast to l + + double length = EdgeLength(E); + //SCRUTE(length); + + double eltSize = 1; +// if (_localLength > 0) eltSize = _localLength; + if (_localLength > 0) + { + double nbseg = ceil(length / _localLength); // integer sup + if (nbseg <= 0) + nbseg = 1; // degenerated edge + eltSize = length / nbseg; + } + else + { + ASSERT(_numberOfSegments > 0); + eltSize = length / _numberOfSegments; + } + + ASSERT(!VFirst.IsNull()); + SMDS_NodeIteratorPtr lid= aMesh.GetSubMesh(VFirst)->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode * idFirst = lid->next(); + + ASSERT(!VLast.IsNull()); + lid=aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode * idLast = lid->next(); + + if (!Curve.IsNull()) + { + GeomAdaptor_Curve C3d(Curve); + GCPnts_UniformAbscissa Discret(C3d, eltSize, f, l); + int NbPoints = Discret.NbPoints(); + //MESSAGE("nb points on edge : "< 1) + { + double epsilon = 0.001; + if (fabs(_scaleFactor - 1.0) > epsilon) + { + double alpha = + pow(_scaleFactor, 1.0 / (_numberOfSegments - 1)); + double d = + length * (1 - pow(alpha, i - 1)) / (1 - pow(alpha, + _numberOfSegments)); + param = d; + } + } + + gp_Pnt P = Curve->Value(param); + + //Add the Node in the DataStructure + //MESSAGE("point "<AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnEdge(node, E); + + // **** edgePosition associe au point = param. + SMDS_EdgePosition* epos = + dynamic_cast(node->GetPosition().get()); + epos->SetUParameter(param); + + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node); + meshDS->SetMeshElementOnShape(edge, E); + idPrev = node; + } + SMDS_MeshEdge* edge = meshDS->AddEdge(idPrev, idLast); + meshDS->SetMeshElementOnShape(edge, E); + } + else + { +// MESSAGE ("Edge Degeneree non traitee --- arret"); +// ASSERT(0); + if (BRep_Tool::Degenerated(E)) + { + // Edge is a degenerated Edge : We put n = 5 points on the edge. + int NbPoints = 5; + BRep_Tool::Range(E, f, l); + double du = (l - f) / (NbPoints - 1); + MESSAGE("************* Degenerated edge! *****************"); + + TopoDS_Vertex V1, V2; + TopExp::Vertices(E, V1, V2); + gp_Pnt P = BRep_Tool::Pnt(V1); + + const SMDS_MeshNode * idPrev = idFirst; + for (int i = 2; i < NbPoints; i++) + { + double param = f + (i - 1) * du; + SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnEdge(node, E); + +// Handle (SMDS_EdgePosition) epos +// = new SMDS_EdgePosition(theSubMesh->GetId(),param); +// node->SetPosition(epos); + SMDS_EdgePosition* epos = + dynamic_cast(node->GetPosition().get()); + epos->SetUParameter(param); + + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node); + meshDS->SetMeshElementOnShape(edge, E); + idPrev = node; + } + SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast); + meshDS->SetMeshElementOnShape(edge, E); + } + else + ASSERT(0); + } + return true; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & StdMeshers_Regular_1D::SaveTo(ostream & save) +{ + return save; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & StdMeshers_Regular_1D::LoadFrom(istream & load) +{ + return load; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & operator <<(ostream & save, StdMeshers_Regular_1D & hyp) +{ + return hyp.SaveTo( save ); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & operator >>(istream & load, StdMeshers_Regular_1D & hyp) +{ + return hyp.LoadFrom( load ); +} diff --git a/src/StdMeshers/StdMeshers_Regular_1D.hxx b/src/StdMeshers/StdMeshers_Regular_1D.hxx new file mode 100644 index 000000000..a68549268 --- /dev/null +++ b/src/StdMeshers/StdMeshers_Regular_1D.hxx @@ -0,0 +1,65 @@ +// SMESH SMESH : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_Regular_1D.hxx +// Moved here from SMESH_Regular_1D.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#ifndef _SMESH_REGULAR_1D_HXX_ +#define _SMESH_REGULAR_1D_HXX_ + +#include "SMESH_1D_Algo.hxx" + +class StdMeshers_LocalLength; +class StdMeshers_NumberOfSegments; + +class StdMeshers_Regular_1D: + public SMESH_1D_Algo +{ +public: + StdMeshers_Regular_1D(int hypId, int studyId, SMESH_Gen* gen); + virtual ~StdMeshers_Regular_1D(); + + virtual bool CheckHypothesis(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus); + + virtual bool Compute(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape); + + ostream & SaveTo(ostream & save); + istream & LoadFrom(istream & load); + friend ostream & operator << (ostream & save, StdMeshers_Regular_1D & hyp); + friend istream & operator >> (istream & load, StdMeshers_Regular_1D & hyp); + +protected: + double _localLength; + int _numberOfSegments; + double _scaleFactor; + const StdMeshers_LocalLength* _hypLocalLength; + const StdMeshers_NumberOfSegments* _hypNumberOfSegments; +}; + +#endif diff --git a/src/StdMeshersGUI/Makefile.in b/src/StdMeshersGUI/Makefile.in new file mode 100644 index 000000000..8c924a23f --- /dev/null +++ b/src/StdMeshersGUI/Makefile.in @@ -0,0 +1,78 @@ +# SMESH StdMeshersGUI : GUI for StdMeshers plugin +# +# Copyright (C) 2003 CEA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +# +# +# +# File : Makefile.in +# Author : Julia DOROVSKIKH +# Module : SMESH +# $Header$ + +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl:${KERNEL_ROOT_DIR}/idl/salome:${MED_ROOT_DIR}/idl/salome + + +@COMMENCE@ + +# .po files to transform in .qm + PO_FILES = \ + StdMeshers_icons.po \ + StdMeshers_msg_en.po + +# Libraries targets +LIB = libStdMeshersGUI.la +LIB_SRC = \ + StdMeshersGUI.cxx \ + StdMeshersGUI_LocalLengthDlg.cxx \ + StdMeshersGUI_NbSegmentsDlg.cxx \ + StdMeshersGUI_MaxElementAreaDlg.cxx \ + StdMeshersGUI_MaxElementVolumeDlg.cxx + +LIB_MOC = \ + StdMeshersGUI_LocalLengthDlg.h \ + StdMeshersGUI_NbSegmentsDlg.h \ + StdMeshersGUI_MaxElementAreaDlg.h \ + StdMeshersGUI_MaxElementVolumeDlg.h + +LIB_CLIENT_IDL = \ + SALOME_Exception.idl \ + SMESH_Gen.idl \ + SMESH_Mesh.idl \ + SMESH_Group.idl \ + SMESH_Filter.idl \ + SMESH_Hypothesis.idl \ + SMESH_BasicHypothesis.idl \ + MED.idl + +LIB_SERVER_IDL = + +# additionnal information to compil and link file + +CPPFLAGS += $(QT_INCLUDES) $(VTK_INCLUDES) $(OGL_INCLUDES) $(OCC_INCLUDES) $(PYTHON_INCLUDES) \ + $(MED2_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome \ + $(BOOST_CPPFLAGS) +CXXFLAGS += -I${KERNEL_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome +#$(OCC_CXXFLAGS) + +LDFLAGS += -lSMESHGUI $(OCC_KERNEL_LIBS) -L${KERNEL_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome + +@CONCLUDE@ diff --git a/src/StdMeshersGUI/StdMeshersGUI.cxx b/src/StdMeshersGUI/StdMeshersGUI.cxx new file mode 100644 index 000000000..e272665f8 --- /dev/null +++ b/src/StdMeshersGUI/StdMeshersGUI.cxx @@ -0,0 +1,225 @@ +// SMESH StdMeshersGUI : GUI for plugged-in meshers +// +// Copyright (C) 2003 CEA +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshersGUI.cxx +// Author : Julia DOROVSKIKH +// Module : SMESH +// $Header$ + +using namespace std; + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESHGUI.h" +#include "SMESHGUI_Hypotheses.h" + +#include "StdMeshersGUI_LocalLengthDlg.h" +#include "StdMeshersGUI_NbSegmentsDlg.h" +#include "StdMeshersGUI_MaxElementAreaDlg.h" +#include "StdMeshersGUI_MaxElementVolumeDlg.h" + +#include "QAD_Desktop.h" +#include "QAD_ResourceMgr.h" + +#include + +//============================================================================= +/*! class HypothesisCreator + * + */ +//============================================================================= +class StdMeshersGUI_HypothesisCreator : public SMESHGUI_GenericHypothesisCreator +{ + public: + StdMeshersGUI_HypothesisCreator (const QString& aHypType, + const QString& aServerLibName, + SMESHGUI* aSMESHGUI) + : myHypType(aHypType), + myServerLibName(aServerLibName), + mySMESHGUI(aSMESHGUI) {} + + virtual void CreateHypothesis (const bool isAlgo, QWidget* parent = 0); + virtual void EditHypothesis (SMESH::SMESH_Hypothesis_ptr theHyp); + + private: + QString myHypType; + QString myServerLibName; + SMESHGUI* mySMESHGUI; +}; + +//============================================================================= +/*! HypothesisCreator::CreateHypothesis + * + */ +//============================================================================= +void StdMeshersGUI_HypothesisCreator::CreateHypothesis + (bool isAlgo, QWidget* parent) +{ + MESSAGE("StdMeshersGUI_HypothesisCreator::CreateHypothesis"); + + // Get default name for hypothesis/algorithm creation + char* sHypType = (char*)myHypType.latin1(); + HypothesisData* aHypData = mySMESHGUI->GetHypothesisData(sHypType); + QString aHypName; + if (aHypData) + aHypName = aHypData->Label; + else + aHypName = myHypType; + + // Create hypothesis/algorithm + if (isAlgo) + { + mySMESHGUI->CreateHypothesis(myHypType, aHypName, isAlgo); + } + else + { + // Show Dialog for hypothesis creation + if (myHypType == "LocalLength") + StdMeshersGUI_LocalLengthDlg *aDlg = new StdMeshersGUI_LocalLengthDlg(myHypType, parent, ""); + else if (myHypType == "NumberOfSegments") + StdMeshersGUI_NbSegmentsDlg *aDlg = new StdMeshersGUI_NbSegmentsDlg(myHypType, parent, ""); + else if (myHypType == "MaxElementArea") + StdMeshersGUI_MaxElementAreaDlg *aDlg = new StdMeshersGUI_MaxElementAreaDlg(myHypType, parent, ""); + else if (myHypType == "MaxElementVolume") + StdMeshersGUI_MaxElementVolumeDlg *aDlg = new StdMeshersGUI_MaxElementVolumeDlg(myHypType, parent, ""); + else if (myHypType == "LengthFromEdges") + mySMESHGUI->CreateHypothesis(myHypType, aHypName, isAlgo); // without GUI + else if (myHypType == "NotConformAllowed") + mySMESHGUI->CreateHypothesis(myHypType, aHypName, isAlgo); // without GUI + else ; + } +} + +//============================================================================= +/*! HypothesisCreator::EditHypothesis + * + */ +//============================================================================= +void StdMeshersGUI_HypothesisCreator::EditHypothesis + (SMESH::SMESH_Hypothesis_ptr theHyp) +{ + MESSAGE("StdMeshersGUI_HypothesisCreator::EditHypothesis"); + + Standard_Boolean res = Standard_True; + SALOMEDS::Study::ListOfSObject_var listSOmesh = + mySMESHGUI->GetMeshesUsingAlgoOrHypothesis(theHyp); + QString Name = theHyp->GetName(); + if (Name.compare("LocalLength") == 0) + { + StdMeshers::StdMeshers_LocalLength_var LL = + StdMeshers::StdMeshers_LocalLength::_narrow(theHyp); + double beforeLength = LL->GetLength() ; + double Length = mySMESHGUI->Parameter(res, + beforeLength, + QObject::tr("SMESH_LOCAL_LENGTH_HYPOTHESIS"), + QObject::tr("SMESH_VALUE"), + 1.0E-5, 1E6, 6); + if (res && Length != beforeLength) + { + LL->SetLength(Length); + for (int i=0; ilength(); i++) + { + mySMESHGUI->GetStudyAPI().ModifiedMesh(listSOmesh[i], false); + } + } + } + else if (Name.compare("NumberOfSegments") == 0) + { + StdMeshers::StdMeshers_NumberOfSegments_var NOS = + StdMeshers::StdMeshers_NumberOfSegments::_narrow(theHyp); + int beforeNbSeg = NOS->GetNumberOfSegments() ; + int NbSeg = mySMESHGUI->Parameter(res, + beforeNbSeg, + QObject::tr("SMESH_NB_SEGMENTS_HYPOTHESIS"), + QObject::tr("SMESH_VALUE"), + 1, 1000000); + if (res && NbSeg != beforeNbSeg) + { + NOS->SetNumberOfSegments(NbSeg); + for (int i=0; ilength(); i++) + { + SALOMEDS::SObject_var SO = listSOmesh[i] ; + mySMESHGUI->GetStudyAPI().ModifiedMesh(listSOmesh[i], false); + } + } + } + else if (Name.compare("MaxElementArea") == 0) + { + StdMeshers::StdMeshers_MaxElementArea_var MEA = + StdMeshers::StdMeshers_MaxElementArea::_narrow(theHyp); + double beforeMaxArea = MEA->GetMaxElementArea(); + double MaxArea = mySMESHGUI->Parameter(res, + beforeMaxArea, + QObject::tr("SMESH_MAX_ELEMENT_AREA_HYPOTHESIS"), + QObject::tr("SMESH_VALUE"), + 1.0E-5, 1E6, 6); + if (res && MaxArea != beforeMaxArea) + { + MEA->SetMaxElementArea(MaxArea); + for (int i=0; ilength(); i++) + { + mySMESHGUI->GetStudyAPI().ModifiedMesh(listSOmesh[i], false); + } + } + } + else if (Name.compare("MaxElementVolume") == 0) + { + StdMeshers::StdMeshers_MaxElementVolume_var MEV = + StdMeshers::StdMeshers_MaxElementVolume::_narrow(theHyp); + double beforeMaxVolume = MEV->GetMaxElementVolume() ; + double MaxVolume = mySMESHGUI->Parameter(res, + beforeMaxVolume, + QObject::tr("SMESH_MAX_ELEMENT_VOLUME_HYPOTHESIS"), + QObject::tr("SMESH_VALUE"), + 1.0E-5, 1E6, 6); + if (res && MaxVolume != beforeMaxVolume) + { + MEV->SetMaxElementVolume(MaxVolume); + for (int i=0; ilength(); i++) + { + mySMESHGUI->GetStudyAPI().ModifiedMesh(listSOmesh[i], false); + } + } + } +// else if (Name.compare("Regular_1D") == 0) +// {} +// else if (Name.compare("MEFISTO_2D") == 0) +// {} + else + {} +} + +//============================================================================= +/*! GetHypothesisCreator + * + */ +//============================================================================= +extern "C" +{ + SMESHGUI_GenericHypothesisCreator* GetHypothesisCreator + (QString aHypType, QString aServerLibName, SMESHGUI* aSMESHGUI) + { + return new StdMeshersGUI_HypothesisCreator + (aHypType, aServerLibName, aSMESHGUI); + } +} diff --git a/src/StdMeshersGUI/StdMeshersGUI_LocalLengthDlg.cxx b/src/StdMeshersGUI/StdMeshersGUI_LocalLengthDlg.cxx new file mode 100644 index 000000000..60e1d42e6 --- /dev/null +++ b/src/StdMeshersGUI/StdMeshersGUI_LocalLengthDlg.cxx @@ -0,0 +1,289 @@ +// SMESH StdMeshersGUI : GUI for StdMeshers plugin +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshersGUI_LocalLengthDlg.cxx +// Moved here from SMESHGUI_LocalLengthDlg.cxx +// Author : Nicolas REJNERI +// Module : SMESH +// $Header$ + +using namespace std; +#include "StdMeshersGUI_LocalLengthDlg.h" +#include "SMESHGUI.h" +#include "SMESHGUI_SpinBox.h" + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "QAD_Application.h" +#include "QAD_Desktop.h" +#include "utilities.h" + +#include "SALOMEGUI_QtCatchCorbaException.hxx" +#include "QAD_MessageBox.h" +#include "QAD_WaitCursor.h" + +// QT Includes +#include +#include +#include +#include +#include +#include + +//================================================================================= +// class : StdMeshersGUI_LocalLengthDlg() +// purpose : Constructs a StdMeshersGUI_LocalLengthDlg which is a child of 'parent', with the +// name 'name' and widget flags set to 'f'. +// The dialog will by default be modeless, unless you set 'modal' to +// TRUE to construct a modal dialog. +//================================================================================= +StdMeshersGUI_LocalLengthDlg::StdMeshersGUI_LocalLengthDlg (const QString& hypType, + QWidget* parent, + const char* name, + bool modal, + WFlags fl) + : QDialog (parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose), + myHypType(hypType) +{ + QPixmap image0(QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr("ICON_DLG_LOCAL_LENGTH"))); + + if ( !name ) + setName( "StdMeshersGUI_LocalLengthDlg" ); + setCaption( tr( "SMESH_LOCAL_LENGTH_TITLE" ) ); + setSizeGripEnabled( TRUE ); + QGridLayout* StdMeshersGUI_LocalLengthDlgLayout = new QGridLayout( this ); + StdMeshersGUI_LocalLengthDlgLayout->setSpacing( 6 ); + StdMeshersGUI_LocalLengthDlgLayout->setMargin( 11 ); + + /***************************************************************/ + iconLabel = new QLabel( this ); + iconLabel->setPixmap( image0 ); + iconLabel->setScaledContents( false ); + iconLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); + typeLabel = new QLabel( this ); + typeLabel->setText( tr( "SMESH_LOCAL_LENGTH_HYPOTHESIS" ) ); + StdMeshersGUI_LocalLengthDlgLayout->addWidget( iconLabel, 0, 0 ); + StdMeshersGUI_LocalLengthDlgLayout->addWidget( typeLabel, 0, 1 ); + + /***************************************************************/ + GroupC1 = new QGroupBox( this, "GroupC1" ); + GroupC1->setTitle( tr( "SMESH_ARGUMENTS" ) ); + GroupC1->setColumnLayout(0, Qt::Vertical ); + GroupC1->layout()->setSpacing( 0 ); + GroupC1->layout()->setMargin( 0 ); + QGridLayout* GroupC1Layout = new QGridLayout( GroupC1->layout() ); + GroupC1Layout->setAlignment( Qt::AlignTop ); + GroupC1Layout->setSpacing( 6 ); + GroupC1Layout->setMargin( 11 ); + + TextLabel_NameHypothesis = new QLabel( GroupC1, "TextLabel_NameHypothesis" ); + TextLabel_NameHypothesis->setText( tr( "SMESH_NAME" ) ); + GroupC1Layout->addWidget( TextLabel_NameHypothesis, 0, 0 ); + + LineEdit_NameHypothesis = new QLineEdit( GroupC1, "LineEdit_NameHypothesis" ); + GroupC1Layout->addWidget( LineEdit_NameHypothesis, 0, 1 ); + + TextLabel_Length = new QLabel(GroupC1 , "TextLabel_Length" ); + TextLabel_Length->setText( tr( "SMESH_LENGTH" ) ); + GroupC1Layout->addWidget( TextLabel_Length, 1, 0 ); + + SpinBox_Length = new SMESHGUI_SpinBox( GroupC1, "SpinBox_Length" ); + GroupC1Layout->addWidget( SpinBox_Length, 1, 1 ); + + StdMeshersGUI_LocalLengthDlgLayout->addMultiCellWidget(GroupC1 , 1, 1, 0, 1 ); + + /***************************************************************/ + GroupButtons = new QGroupBox( this, "GroupButtons" ); + GroupButtons->setColumnLayout(0, Qt::Vertical ); + GroupButtons->layout()->setSpacing( 0 ); + GroupButtons->layout()->setMargin( 0 ); + QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() ); + GroupButtonsLayout->setAlignment( Qt::AlignTop ); + GroupButtonsLayout->setSpacing( 6 ); + GroupButtonsLayout->setMargin( 11 ); + buttonOk = new QPushButton( GroupButtons, "buttonOk" ); + buttonOk->setText( tr( "SMESH_BUT_OK" ) ); + buttonOk->setAutoDefault( TRUE ); + buttonOk->setDefault( TRUE ); + GroupButtonsLayout->addWidget( buttonOk, 0, 0 ); + buttonApply = new QPushButton( GroupButtons, "buttonApply" ); + buttonApply->setText( tr( "SMESH_BUT_APPLY" ) ); + buttonApply->setAutoDefault( TRUE ); + GroupButtonsLayout->addWidget( buttonApply, 0, 1 ); + QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); + GroupButtonsLayout->addItem( spacer, 0, 2 ); + buttonCancel = new QPushButton( GroupButtons, "buttonCancel" ); + buttonCancel->setText( tr( "SMESH_BUT_CLOSE" ) ); + buttonCancel->setAutoDefault( TRUE ); + GroupButtonsLayout->addWidget( buttonCancel, 0, 3 ); + StdMeshersGUI_LocalLengthDlgLayout->addMultiCellWidget( GroupButtons, 2, 2, 0, 1 ); + + /***************************************************************/ + Init() ; +} + + +//================================================================================= +// function : ~StdMeshersGUI_LocalLengthDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +StdMeshersGUI_LocalLengthDlg::~StdMeshersGUI_LocalLengthDlg() +{ + // no need to delete child widgets, Qt does it all for us +} + + +//================================================================================= +// function : Init() +// purpose : +//================================================================================= +void StdMeshersGUI_LocalLengthDlg::Init() +{ + /* min, max, step and decimals for spin boxes */ + SpinBox_Length->RangeStepAndValidator( 0.001, 999.999, 1.0, 3 ) ; + SpinBox_Length->SetValue( 1.0 ) ; + + mySMESHGUI = SMESHGUI::GetSMESHGUI() ; + + char* sHypType = (char*)myHypType.latin1(); + HypothesisData* aHypData = mySMESHGUI->GetHypothesisData(sHypType); + LineEdit_NameHypothesis->setText( aHypData ? aHypData->Label : "" ); + + mySMESHGUI->SetActiveDialogBox( (QDialog*)this ) ; + + /* signals and slots connections */ + connect( buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk()) ); + connect( buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()) ) ; + connect( buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()) ); + + connect( mySMESHGUI, SIGNAL ( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ; + connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) ) ; + + /* Move widget on the botton right corner of main widget */ + int x, y ; + mySMESHGUI->DefineDlgPosition( this, x, y ) ; + this->move( x, y ) ; + this->show() ; /* displays Dialog */ +} + + +//================================================================================= +// function : ClickOnOk() +// purpose : +//================================================================================= +void StdMeshersGUI_LocalLengthDlg::ClickOnOk() +{ + if ( this->ClickOnApply() ) + this->ClickOnCancel() ; +} + +//================================================================================= +// function : ClickOnApply() +// purpose : +//================================================================================= +bool StdMeshersGUI_LocalLengthDlg::ClickOnApply() +{ + QString myHypName = LineEdit_NameHypothesis->text().stripWhiteSpace(); + if ( myHypName.isEmpty() ) { + QAD_MessageBox::warn1( this, tr( "SMESH_WRN_WARNING" ), tr( "SMESH_WRN_EMPTY_NAME" ), tr( "SMESH_BUT_OK" ) ); + return false; + } + + double myLength = SpinBox_Length->GetValue(); + + QAD_WaitCursor wc; + try { + SMESH::SMESH_Hypothesis_var Hyp = SMESH::SMESH_Hypothesis::_narrow + (mySMESHGUI->CreateHypothesis(myHypType, + myHypName, + false)); // isAlgorithm + StdMeshers::StdMeshers_LocalLength_var LL = + StdMeshers::StdMeshers_LocalLength::_narrow(Hyp); + if (!LL->_is_nil()) + LL->SetLength(myLength); + } + catch (const SALOME::SALOME_Exception& S_ex) { + wc.stop(); + QtCatchCorbaException(S_ex); + return false; + } + return true; +} + + +//================================================================================= +// function : ClickOnCancel() +// purpose : +//================================================================================= +void StdMeshersGUI_LocalLengthDlg::ClickOnCancel() +{ + close(); +} + +//================================================================================= +// function : DeactivateActiveDialog() +// purpose : +//================================================================================= +void StdMeshersGUI_LocalLengthDlg::DeactivateActiveDialog() +{ + iconLabel->setEnabled(false) ; + typeLabel->setEnabled(false) ; + GroupC1->setEnabled(false) ; + GroupButtons->setEnabled(false) ; +} + + +//================================================================================= +// function : ActivateThisDialog() +// purpose : +//================================================================================= +void StdMeshersGUI_LocalLengthDlg::ActivateThisDialog() +{ + mySMESHGUI->EmitSignalDeactivateDialog() ; + iconLabel->setEnabled(true) ; + typeLabel->setEnabled(true) ; + GroupC1->setEnabled(true) ; + GroupButtons->setEnabled(true) ; +} + + +//================================================================================= +// function : enterEvent() +// purpose : +//================================================================================= +void StdMeshersGUI_LocalLengthDlg::enterEvent(QEvent* e) +{ + ActivateThisDialog() ; +} + + +//================================================================================= +// function : closeEvent() +// purpose : +//================================================================================= +void StdMeshersGUI_LocalLengthDlg::closeEvent( QCloseEvent* e ) +{ + mySMESHGUI->ResetState(); + QDialog::closeEvent( e ); +} diff --git a/src/StdMeshersGUI/StdMeshersGUI_LocalLengthDlg.h b/src/StdMeshersGUI/StdMeshersGUI_LocalLengthDlg.h new file mode 100644 index 000000000..8b3dda580 --- /dev/null +++ b/src/StdMeshersGUI/StdMeshersGUI_LocalLengthDlg.h @@ -0,0 +1,89 @@ +// SMESH SMESHGUI : GUI for SMESH component +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshersGUI_LocalLengthDlg.h +// Moved here from SMESHGUI_LocalLengthDlg.h +// Author : Nicolas REJNERI +// Module : SMESH +// $Header$ + +#ifndef DIALOGBOX_LOCAL_LENGTH_H +#define DIALOGBOX_LOCAL_LENGTH_H + +// QT Includes +#include + +class QGroupBox; +class QLabel; +class QLineEdit; +class QPushButton; +class SMESHGUI; +class SMESHGUI_SpinBox; + +//================================================================================= +// class : StdMeshersGUI_LocalLengthDlg +// purpose : +//================================================================================= +class StdMeshersGUI_LocalLengthDlg : public QDialog +{ + Q_OBJECT + +public: + StdMeshersGUI_LocalLengthDlg (const QString& hypType, + QWidget* parent = 0, + const char* name = 0, + bool modal = FALSE, + WFlags fl = 0); + ~StdMeshersGUI_LocalLengthDlg (); + +private: + + void Init() ; + void closeEvent( QCloseEvent* e ) ; + void enterEvent ( QEvent * ) ; + + SMESHGUI* mySMESHGUI ; + QString myHypType ; + + QLabel* iconLabel; + QLabel* typeLabel; + QGroupBox* GroupC1; + QLabel* TextLabel_NameHypothesis ; + QLineEdit* LineEdit_NameHypothesis ; + QLabel* TextLabel_Length ; + SMESHGUI_SpinBox* SpinBox_Length ; + QGroupBox* GroupButtons; + QPushButton* buttonOk; + QPushButton* buttonApply; + QPushButton* buttonCancel; + +private slots: + + void ClickOnOk(); + void ClickOnCancel(); + bool ClickOnApply(); + void DeactivateActiveDialog() ; + void ActivateThisDialog() ; +}; + +#endif // DIALOGBOX_LOCAL_LENGTH_H diff --git a/src/StdMeshersGUI/StdMeshersGUI_MaxElementAreaDlg.cxx b/src/StdMeshersGUI/StdMeshersGUI_MaxElementAreaDlg.cxx new file mode 100644 index 000000000..ae99f6e26 --- /dev/null +++ b/src/StdMeshersGUI/StdMeshersGUI_MaxElementAreaDlg.cxx @@ -0,0 +1,291 @@ +// SMESH SMESHGUI : GUI for SMESH component +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshersGUI_MaxElementAreaDlg.cxx +// Moved here from SMESHGUI_MaxElementAreaDlg.cxx +// Author : Nicolas REJNERI +// Module : SMESH +// $Header$ + +using namespace std; +#include "StdMeshersGUI_MaxElementAreaDlg.h" +#include "SMESHGUI.h" +#include "SMESHGUI_SpinBox.h" + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "QAD_Application.h" +#include "QAD_Desktop.h" +#include "utilities.h" + +#include "SALOMEGUI_QtCatchCorbaException.hxx" +#include "QAD_MessageBox.h" +#include "QAD_WaitCursor.h" + +// QT Includes +#include +#include +#include +#include +#include +#include + +//================================================================================= +// class : StdMeshersGUI_MaxElementAreaDlg() +// purpose : Constructs a StdMeshersGUI_MaxElementAreaDlg which is a child of 'parent', with the +// name 'name' and widget flags set to 'f'. +// The dialog will by default be modeless, unless you set 'modal' to +// TRUE to construct a modal dialog. +//================================================================================= +StdMeshersGUI_MaxElementAreaDlg::StdMeshersGUI_MaxElementAreaDlg (const QString& hypType, + QWidget* parent, + const char* name, + bool modal, + WFlags fl) + : QDialog (parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose), + myHypType(hypType) +{ + QPixmap image0(QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr("ICON_DLG_MAX_ELEMENT_AREA"))); + + if ( !name ) + setName( "StdMeshersGUI_MaxElementAreaDlg" ); + setCaption( tr( "SMESH_MAX_ELEMENT_AREA_TITLE" ) ); + setSizeGripEnabled( TRUE ); + QGridLayout* StdMeshersGUI_MaxElementAreaDlgLayout = new QGridLayout( this ); + StdMeshersGUI_MaxElementAreaDlgLayout->setSpacing( 6 ); + StdMeshersGUI_MaxElementAreaDlgLayout->setMargin( 11 ); + + /***************************************************************/ + iconLabel = new QLabel( this ); + iconLabel->setPixmap( image0 ); + iconLabel->setScaledContents( false ); + iconLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); + typeLabel = new QLabel( this ); + typeLabel->setText( tr( "SMESH_MAX_ELEMENT_AREA_HYPOTHESIS" ) ); + StdMeshersGUI_MaxElementAreaDlgLayout->addWidget( iconLabel, 0, 0 ); + StdMeshersGUI_MaxElementAreaDlgLayout->addWidget( typeLabel, 0, 1 ); + + /***************************************************************/ + GroupC1 = new QGroupBox( this, "GroupC1" ); + GroupC1->setTitle( tr( "SMESH_ARGUMENTS" ) ); + GroupC1->setColumnLayout(0, Qt::Vertical ); + GroupC1->layout()->setSpacing( 0 ); + GroupC1->layout()->setMargin( 0 ); + QGridLayout* GroupC1Layout = new QGridLayout( GroupC1->layout() ); + GroupC1Layout->setAlignment( Qt::AlignTop ); + GroupC1Layout->setSpacing( 6 ); + GroupC1Layout->setMargin( 11 ); + + TextLabel_NameHypothesis = new QLabel( GroupC1, "TextLabel_NameHypothesis" ); + TextLabel_NameHypothesis->setText( tr( "SMESH_NAME" ) ); + GroupC1Layout->addWidget( TextLabel_NameHypothesis, 0, 0 ); + + LineEdit_NameHypothesis = new QLineEdit( GroupC1, "LineEdit_NameHypothesis" ); + GroupC1Layout->addWidget( LineEdit_NameHypothesis, 0, 1 ); + + TextLabel_MaxElementArea = new QLabel(GroupC1 , "TextLabel_MaxElementArea" ); + TextLabel_MaxElementArea->setText( tr( "SMESH_MAX_ELEMENT_AREA" ) ); + GroupC1Layout->addWidget( TextLabel_MaxElementArea, 1, 0 ); + + SpinBox_MaxElementArea = new SMESHGUI_SpinBox( GroupC1, "SpinBox_MaxElementArea" ) ; + GroupC1Layout->addWidget( SpinBox_MaxElementArea, 1, 1 ); + + StdMeshersGUI_MaxElementAreaDlgLayout->addMultiCellWidget(GroupC1 , 1, 1, 0, 1); + + /***************************************************************/ + GroupButtons = new QGroupBox( this, "GroupButtons" ); + GroupButtons->setColumnLayout(0, Qt::Vertical ); + GroupButtons->layout()->setSpacing( 0 ); + GroupButtons->layout()->setMargin( 0 ); + QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() ); + GroupButtonsLayout->setAlignment( Qt::AlignTop ); + GroupButtonsLayout->setSpacing( 6 ); + GroupButtonsLayout->setMargin( 11 ); + buttonOk = new QPushButton( GroupButtons, "buttonOk" ); + buttonOk->setText( tr( "SMESH_BUT_OK" ) ); + buttonOk->setAutoDefault( TRUE ); + buttonOk->setDefault( TRUE ); + GroupButtonsLayout->addWidget( buttonOk, 0, 0 ); + buttonApply = new QPushButton( GroupButtons, "buttonApply" ); + buttonApply->setText( tr( "SMESH_BUT_APPLY" ) ); + buttonApply->setAutoDefault( TRUE ); + GroupButtonsLayout->addWidget( buttonApply, 0, 1 ); + QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); + GroupButtonsLayout->addItem( spacer, 0, 2 ); + buttonCancel = new QPushButton( GroupButtons, "buttonCancel" ); + buttonCancel->setText( tr( "SMESH_BUT_CLOSE" ) ); + buttonCancel->setAutoDefault( TRUE ); + GroupButtonsLayout->addWidget( buttonCancel, 0, 3 ); + StdMeshersGUI_MaxElementAreaDlgLayout->addMultiCellWidget( GroupButtons, 2, 2, 0, 1 ); + + /***************************************************************/ + Init() ; +} + + +//================================================================================= +// function : ~StdMeshersGUI_MaxElementAreaDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +StdMeshersGUI_MaxElementAreaDlg::~StdMeshersGUI_MaxElementAreaDlg() +{ + // no need to delete child widgets, Qt does it all for us +} + + +//================================================================================= +// function : Init() +// purpose : +//================================================================================= +void StdMeshersGUI_MaxElementAreaDlg::Init() +{ + /* min, max, step and decimals for spin boxes */ + SpinBox_MaxElementArea->setPrecision( 10 ); + SpinBox_MaxElementArea->RangeStepAndValidator( 0.001, 999999.999, 1.0, 3 ) ; + SpinBox_MaxElementArea->SetValue( 1.0 ) ; /* is myMaxElementArea */ + + mySMESHGUI = SMESHGUI::GetSMESHGUI() ; + + char* sHypType = (char*)myHypType.latin1(); + HypothesisData* aHypData = mySMESHGUI->GetHypothesisData(sHypType); + LineEdit_NameHypothesis->setText( aHypData ? aHypData->Label : "" ); + + mySMESHGUI->SetActiveDialogBox( (QDialog*)this ) ; + + /* signals and slots connections */ + connect( buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk()) ); + connect( buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()) ) ; + connect( buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()) ); + + connect( mySMESHGUI, SIGNAL ( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ; + connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) ) ; + + /* Move widget on the botton right corner of main widget */ + int x, y ; + mySMESHGUI->DefineDlgPosition( this, x, y ) ; + this->move( x, y ) ; + this->show() ; /* displays Dialog */ +} + + +//================================================================================= +// function : ClickOnOk() +// purpose : +//================================================================================= +void StdMeshersGUI_MaxElementAreaDlg::ClickOnOk() +{ + if ( this->ClickOnApply() ) + this->ClickOnCancel() ; +} + +//================================================================================= +// function : ClickOnApply() +// purpose : +//================================================================================= +bool StdMeshersGUI_MaxElementAreaDlg::ClickOnApply() +{ + QString myHypName = LineEdit_NameHypothesis->text().stripWhiteSpace(); + if ( myHypName.isEmpty() ) { + QAD_MessageBox::warn1( this, tr( "SMESH_WRN_WARNING" ), tr( "SMESH_WRN_EMPTY_NAME" ), tr( "SMESH_BUT_OK" ) ); + return false; + } + + double myMaxElementArea = SpinBox_MaxElementArea->GetValue(); + + QAD_WaitCursor wc; + try { + SMESH::SMESH_Hypothesis_var Hyp = SMESH::SMESH_Hypothesis::_narrow + (mySMESHGUI->CreateHypothesis(myHypType, + myHypName, + false)); // isAlgorithm + StdMeshers::StdMeshers_MaxElementArea_var MaxElArea = + StdMeshers::StdMeshers_MaxElementArea::_narrow(Hyp); + if (!MaxElArea->_is_nil()) + MaxElArea->SetMaxElementArea(myMaxElementArea); + } + catch (const SALOME::SALOME_Exception& S_ex) { + wc.stop(); + QtCatchCorbaException(S_ex); + return false; + } + return true; +} + + +//================================================================================= +// function : ClickOnCancel() +// purpose : +//================================================================================= +void StdMeshersGUI_MaxElementAreaDlg::ClickOnCancel() +{ + close(); +} + + +//================================================================================= +// function : DeactivateActiveDialog() +// purpose : +//================================================================================= +void StdMeshersGUI_MaxElementAreaDlg::DeactivateActiveDialog() +{ + iconLabel->setEnabled(false) ; + typeLabel->setEnabled(false) ; + GroupC1->setEnabled(false) ; + GroupButtons->setEnabled(false) ; +} + + +//================================================================================= +// function : ActivateThisDialog() +// purpose : +//================================================================================= +void StdMeshersGUI_MaxElementAreaDlg::ActivateThisDialog() +{ + mySMESHGUI->EmitSignalDeactivateDialog() ; + iconLabel->setEnabled(true) ; + typeLabel->setEnabled(true) ; + GroupC1->setEnabled(true) ; + GroupButtons->setEnabled(true) ; +} + + +//================================================================================= +// function : enterEvent() +// purpose : +//================================================================================= +void StdMeshersGUI_MaxElementAreaDlg::enterEvent(QEvent* e) +{ + ActivateThisDialog() ; +} + + +//================================================================================= +// function : closeEvent() +// purpose : +//================================================================================= +void StdMeshersGUI_MaxElementAreaDlg::closeEvent( QCloseEvent* e ) +{ + mySMESHGUI->ResetState(); + QDialog::closeEvent( e ); +} diff --git a/src/StdMeshersGUI/StdMeshersGUI_MaxElementAreaDlg.h b/src/StdMeshersGUI/StdMeshersGUI_MaxElementAreaDlg.h new file mode 100644 index 000000000..e95f3cb08 --- /dev/null +++ b/src/StdMeshersGUI/StdMeshersGUI_MaxElementAreaDlg.h @@ -0,0 +1,89 @@ +// SMESH SMESHGUI : GUI for SMESH component +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshersGUI_MaxElementAreaDlg.h +// Moved here from SMESHGUI_MaxElementAreaDlg.h +// Author : Nicolas REJNERI +// Module : SMESH +// $Header$ + +#ifndef DIALOGBOX_MAX_ELEMENT_AREA_H +#define DIALOGBOX_MAX_ELEMENT_AREA_H + +// QT Includes +#include + +class QGroupBox; +class QLabel; +class QLineEdit; +class QPushButton; +class SMESHGUI; +class SMESHGUI_SpinBox; + +//================================================================================= +// class : StdMeshersGUI_MaxElementAreaDlg +// purpose : +//================================================================================= +class StdMeshersGUI_MaxElementAreaDlg : public QDialog +{ + Q_OBJECT + +public: + StdMeshersGUI_MaxElementAreaDlg (const QString& hypType, + QWidget* parent = 0, + const char* name = 0, + bool modal = FALSE, + WFlags fl = 0 ); + ~StdMeshersGUI_MaxElementAreaDlg (); + +private: + + void Init() ; + void closeEvent( QCloseEvent* e ) ; + void enterEvent ( QEvent * ) ; + + SMESHGUI* mySMESHGUI ; + QString myHypType ; + + QLabel* iconLabel; + QLabel* typeLabel; + QGroupBox* GroupC1; + QLabel* TextLabel_NameHypothesis ; + QLineEdit* LineEdit_NameHypothesis ; + QLabel* TextLabel_MaxElementArea ; + SMESHGUI_SpinBox* SpinBox_MaxElementArea ; + QGroupBox* GroupButtons; + QPushButton* buttonApply; + QPushButton* buttonOk; + QPushButton* buttonCancel; + +private slots: + + void ClickOnOk(); + void ClickOnCancel(); + bool ClickOnApply(); + void DeactivateActiveDialog() ; + void ActivateThisDialog() ; +}; + +#endif // DIALOGBOX_MAX_ELEMENT_AREA_H diff --git a/src/StdMeshersGUI/StdMeshersGUI_MaxElementVolumeDlg.cxx b/src/StdMeshersGUI/StdMeshersGUI_MaxElementVolumeDlg.cxx new file mode 100644 index 000000000..c5a75ee13 --- /dev/null +++ b/src/StdMeshersGUI/StdMeshersGUI_MaxElementVolumeDlg.cxx @@ -0,0 +1,290 @@ +// SMESH SMESHGUI : GUI for SMESH component +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshersGUI_MaxElementVolumeDlg.cxx +// Moved here from SMESHGUI_MaxElementVolumeDlg.cxx +// Author : Nicolas REJNERI +// Module : SMESH +// $Header$ + +using namespace std; +#include "StdMeshersGUI_MaxElementVolumeDlg.h" +#include "SMESHGUI.h" +#include "SMESHGUI_SpinBox.h" + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "QAD_Application.h" +#include "QAD_Desktop.h" +#include "utilities.h" + +#include "SALOMEGUI_QtCatchCorbaException.hxx" +#include "QAD_MessageBox.h" +#include "QAD_WaitCursor.h" + +// QT Includes +#include +#include +#include +#include +#include +#include + +//================================================================================= +// class : StdMeshersGUI_MaxElementVolumeDlg() +// purpose : Constructs a StdMeshersGUI_MaxElementVolumeDlg which is a child of 'parent', with the +// name 'name' and widget flags set to 'f'. +// The dialog will by default be modeless, unless you set 'modal' to +// TRUE to construct a modal dialog. +//================================================================================= +StdMeshersGUI_MaxElementVolumeDlg::StdMeshersGUI_MaxElementVolumeDlg (const QString& hypType, + QWidget* parent, + const char* name, + bool modal, WFlags fl) + : QDialog (parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose), + myHypType(hypType) +{ + QPixmap image0(QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr("ICON_DLG_MAX_ELEMENT_VOLUME"))); + + if ( !name ) + setName( "StdMeshersGUI_MaxElementVolumeDlg" ); + setCaption( tr( "SMESH_MAX_ELEMENT_VOLUME_TITLE" ) ); + setSizeGripEnabled( TRUE ); + QGridLayout* StdMeshersGUI_MaxElementVolumeDlgLayout = new QGridLayout( this ); + StdMeshersGUI_MaxElementVolumeDlgLayout->setSpacing( 6 ); + StdMeshersGUI_MaxElementVolumeDlgLayout->setMargin( 11 ); + + /***************************************************************/ + iconLabel = new QLabel( this ); + iconLabel->setPixmap( image0 ); + iconLabel->setScaledContents( false ); + iconLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); + typeLabel = new QLabel( this ); + typeLabel->setText( tr( "SMESH_MAX_ELEMENT_VOLUME_HYPOTHESIS" ) ); + StdMeshersGUI_MaxElementVolumeDlgLayout->addWidget( iconLabel, 0, 0 ); + StdMeshersGUI_MaxElementVolumeDlgLayout->addWidget( typeLabel, 0, 1 ); + + /***************************************************************/ + GroupButtons = new QGroupBox( this, "GroupButtons" ); + GroupButtons->setColumnLayout(0, Qt::Vertical ); + GroupButtons->layout()->setSpacing( 0 ); + GroupButtons->layout()->setMargin( 0 ); + QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() ); + GroupButtonsLayout->setAlignment( Qt::AlignTop ); + GroupButtonsLayout->setSpacing( 6 ); + GroupButtonsLayout->setMargin( 11 ); + buttonOk = new QPushButton( GroupButtons, "buttonOk" ); + buttonOk->setText( tr( "SMESH_BUT_OK" ) ); + buttonOk->setAutoDefault( TRUE ); + buttonOk->setDefault( TRUE ); + GroupButtonsLayout->addWidget( buttonOk, 0, 0 ); + buttonApply = new QPushButton( GroupButtons, "buttonApply" ); + buttonApply->setText( tr( "SMESH_BUT_APPLY" ) ); + buttonApply->setAutoDefault( TRUE ); + GroupButtonsLayout->addWidget( buttonApply, 0, 1 ); + QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); + GroupButtonsLayout->addItem( spacer, 0, 2 ); + buttonCancel = new QPushButton( GroupButtons, "buttonCancel" ); + buttonCancel->setText( tr( "SMESH_BUT_CLOSE" ) ); + buttonCancel->setAutoDefault( TRUE ); + GroupButtonsLayout->addWidget( buttonCancel, 0, 3 ); + StdMeshersGUI_MaxElementVolumeDlgLayout->addMultiCellWidget( GroupButtons, 2, 2, 0, 1 ); + + /***************************************************************/ + GroupC1 = new QGroupBox( this, "GroupC1" ); + GroupC1->setTitle( tr( "SMESH_ARGUMENTS" ) ); + GroupC1->setColumnLayout(0, Qt::Vertical ); + GroupC1->layout()->setSpacing( 0 ); + GroupC1->layout()->setMargin( 0 ); + QGridLayout* GroupC1Layout = new QGridLayout( GroupC1->layout() ); + GroupC1Layout->setAlignment( Qt::AlignTop ); + GroupC1Layout->setSpacing( 6 ); + GroupC1Layout->setMargin( 11 ); + + TextLabel_NameHypothesis = new QLabel( GroupC1, "TextLabel_NameHypothesis" ); + TextLabel_NameHypothesis->setText( tr( "SMESH_NAME" ) ); + GroupC1Layout->addWidget( TextLabel_NameHypothesis, 0, 0 ); + + LineEdit_NameHypothesis = new QLineEdit( GroupC1, "LineEdit_NameHypothesis" ); + GroupC1Layout->addWidget( LineEdit_NameHypothesis, 0, 1 ); + + TextLabel_MaxElementVolume = new QLabel(GroupC1 , "TextLabel_MaxElementVolume" ); + TextLabel_MaxElementVolume->setText( tr( "SMESH_MAX_ELEMENT_VOLUME" ) ); + GroupC1Layout->addWidget( TextLabel_MaxElementVolume, 1, 0 ); + + SpinBox_MaxElementVolume = new SMESHGUI_SpinBox( GroupC1, "SpinBox_MaxElementVolume" ) ; + GroupC1Layout->addWidget( SpinBox_MaxElementVolume, 1, 1 ); + + StdMeshersGUI_MaxElementVolumeDlgLayout->addMultiCellWidget(GroupC1 , 1, 1, 0, 1 ); + + /***************************************************************/ + Init() ; +} + + +//================================================================================= +// function : ~StdMeshersGUI_MaxElementVolumeDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +StdMeshersGUI_MaxElementVolumeDlg::~StdMeshersGUI_MaxElementVolumeDlg() +{ + // no need to delete child widgets, Qt does it all for us +} + + +//================================================================================= +// function : Init() +// purpose : +//================================================================================= +void StdMeshersGUI_MaxElementVolumeDlg::Init() +{ + /* min, max, step and decimals for spin boxes */ + SpinBox_MaxElementVolume->setPrecision( 10 ); + SpinBox_MaxElementVolume->RangeStepAndValidator( 0.001, 999999.999, 1.0, 3 ) ; + SpinBox_MaxElementVolume->SetValue( 1.0 ) ; /* is myMaxElementVolume */ + + mySMESHGUI = SMESHGUI::GetSMESHGUI() ; + + char* sHypType = (char*)myHypType.latin1(); + HypothesisData* aHypData = mySMESHGUI->GetHypothesisData(sHypType); + LineEdit_NameHypothesis->setText( aHypData ? aHypData->Label : "" ); + + mySMESHGUI->SetActiveDialogBox( (QDialog*)this ) ; + + /* signals and slots connections */ + connect( buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk()) ); + connect( buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()) ) ; + connect( buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()) ); + + connect( mySMESHGUI, SIGNAL ( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ; + connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) ) ; + + /* Move widget on the botton right corner of main widget */ + int x, y ; + mySMESHGUI->DefineDlgPosition( this, x, y ) ; + this->move( x, y ) ; + this->show() ; /* displays Dialog */ +} + + +//================================================================================= +// function : ClickOnOk() +// purpose : +//================================================================================= +void StdMeshersGUI_MaxElementVolumeDlg::ClickOnOk() +{ + if ( this->ClickOnApply() ) + this->ClickOnCancel() ; +} + +//================================================================================= +// function : ClickOnApply() +// purpose : +//================================================================================= +bool StdMeshersGUI_MaxElementVolumeDlg::ClickOnApply() +{ + QString myHypName = LineEdit_NameHypothesis->text().stripWhiteSpace(); + if ( myHypName.isEmpty() ) { + QAD_MessageBox::warn1( this, tr( "SMESH_WRN_WARNING" ), tr( "SMESH_WRN_EMPTY_NAME" ), tr( "SMESH_BUT_OK" ) ); + return false; + } + + double myMaxElementVolume = SpinBox_MaxElementVolume->GetValue(); + + QAD_WaitCursor wc; + try { + SMESH::SMESH_Hypothesis_var Hyp = SMESH::SMESH_Hypothesis::_narrow + (mySMESHGUI->CreateHypothesis(myHypType, + myHypName, + false)); // isAlgorithm + StdMeshers::StdMeshers_MaxElementVolume_var MaxElVolume = + StdMeshers::StdMeshers_MaxElementVolume::_narrow(Hyp); + if (!MaxElVolume->_is_nil()) + MaxElVolume->SetMaxElementVolume(myMaxElementVolume); + } + catch (const SALOME::SALOME_Exception& S_ex) { + wc.stop(); + QtCatchCorbaException(S_ex); + return false; + } + return true; +} + + +//================================================================================= +// function : ClickOnCancel() +// purpose : +//================================================================================= +void StdMeshersGUI_MaxElementVolumeDlg::ClickOnCancel() +{ + close(); +} + + +//================================================================================= +// function : DeactivateActiveDialog() +// purpose : +//================================================================================= +void StdMeshersGUI_MaxElementVolumeDlg::DeactivateActiveDialog() +{ + iconLabel->setEnabled(false) ; + typeLabel->setEnabled(false) ; + GroupC1->setEnabled(false) ; + GroupButtons->setEnabled(false) ; +} + + +//================================================================================= +// function : ActivateThisDialog() +// purpose : +//================================================================================= +void StdMeshersGUI_MaxElementVolumeDlg::ActivateThisDialog() +{ + mySMESHGUI->EmitSignalDeactivateDialog() ; + iconLabel->setEnabled(true) ; + typeLabel->setEnabled(true) ; + GroupC1->setEnabled(true) ; + GroupButtons->setEnabled(true) ; +} + + +//================================================================================= +// function : enterEvent() +// purpose : +//================================================================================= +void StdMeshersGUI_MaxElementVolumeDlg::enterEvent(QEvent* e) +{ + ActivateThisDialog() ; +} + + +//================================================================================= +// function : closeEvent() +// purpose : +//================================================================================= +void StdMeshersGUI_MaxElementVolumeDlg::closeEvent( QCloseEvent* e ) +{ + mySMESHGUI->ResetState(); + QDialog::closeEvent( e ); +} diff --git a/src/StdMeshersGUI/StdMeshersGUI_MaxElementVolumeDlg.h b/src/StdMeshersGUI/StdMeshersGUI_MaxElementVolumeDlg.h new file mode 100644 index 000000000..b31215777 --- /dev/null +++ b/src/StdMeshersGUI/StdMeshersGUI_MaxElementVolumeDlg.h @@ -0,0 +1,89 @@ +// SMESH SMESHGUI : GUI for SMESH component +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshersGUI_MaxElementVolumeDlg.h +// Moved here from SMESHGUI_MaxElementVolumeDlg.h +// Author : Nicolas REJNERI +// Module : SMESH +// $Header$ + +#ifndef DIALOGBOX_MAX_ELEMENT_VOLUME_H +#define DIALOGBOX_MAX_ELEMENT_VOLUME_H + +// QT Includes +#include + +class QGroupBox; +class QLabel; +class QLineEdit; +class QPushButton; +class SMESHGUI; +class SMESHGUI_SpinBox; + +//================================================================================= +// class : StdMeshersGUI_MaxElementVolumeDlg +// purpose : +//================================================================================= +class StdMeshersGUI_MaxElementVolumeDlg : public QDialog +{ + Q_OBJECT + +public: + StdMeshersGUI_MaxElementVolumeDlg (const QString& hypType, + QWidget* parent = 0, + const char* name = 0, + bool modal = FALSE, + WFlags fl = 0 ); + ~StdMeshersGUI_MaxElementVolumeDlg (); + +private: + + void Init() ; + void closeEvent( QCloseEvent* e ) ; + void enterEvent ( QEvent * ) ; + + SMESHGUI* mySMESHGUI ; + QString myHypType ; + + QLabel* iconLabel; + QLabel* typeLabel; + QGroupBox* GroupButtons; + QPushButton* buttonApply; + QPushButton* buttonOk; + QPushButton* buttonCancel; + QGroupBox* GroupC1; + QLabel* TextLabel_NameHypothesis ; + QLineEdit* LineEdit_NameHypothesis ; + QLabel* TextLabel_MaxElementVolume ; + SMESHGUI_SpinBox* SpinBox_MaxElementVolume ; + +private slots: + + void ClickOnOk(); + void ClickOnCancel(); + bool ClickOnApply(); + void DeactivateActiveDialog() ; + void ActivateThisDialog() ; +}; + +#endif // DIALOGBOX_MAX_ELEMENT_VOLUME_H diff --git a/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsDlg.cxx b/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsDlg.cxx new file mode 100644 index 000000000..6798c381a --- /dev/null +++ b/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsDlg.cxx @@ -0,0 +1,289 @@ +// SMESH SMESHGUI : GUI for SMESH component +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshersGUI_NbSegmentsDlg.cxx +// Moved here from SMESHGUI_NbSegmentsDlg.cxx +// Author : Nicolas REJNERI +// Module : SMESH +// $Header$ + +using namespace std; +#include "StdMeshersGUI_NbSegmentsDlg.h" +#include "SMESHGUI.h" + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "QAD_Application.h" +#include "QAD_Desktop.h" +#include "utilities.h" + +#include "SALOMEGUI_QtCatchCorbaException.hxx" +#include "QAD_MessageBox.h" +#include "QAD_WaitCursor.h" + +// QT Includes +#include +#include +#include +#include +#include +#include +#include + +//================================================================================= +// class : StdMeshersGUI_NbSegmentsDlg() +// purpose : Constructs a StdMeshersGUI_NbSegmentsDlg which is a child of 'parent', with the +// name 'name' and widget flags set to 'f'. +// The dialog will by default be modeless, unless you set 'modal' to +// TRUE to construct a modal dialog. +//================================================================================= +StdMeshersGUI_NbSegmentsDlg::StdMeshersGUI_NbSegmentsDlg (const QString& hypType, + QWidget* parent, + const char* name, + bool modal, + WFlags fl) + : QDialog (parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose), + myHypType(hypType) +{ + QPixmap image0(QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr("ICON_DLG_NB_SEGMENTS"))); + + if ( !name ) + setName( "StdMeshersGUI_NbSegmentsDlg" ); + setCaption( tr( "SMESH_NB_SEGMENTS_TITLE" ) ); + setSizeGripEnabled( TRUE ); + QGridLayout* StdMeshersGUI_NbSegmentsDlgLayout = new QGridLayout( this ); + StdMeshersGUI_NbSegmentsDlgLayout->setSpacing( 6 ); + StdMeshersGUI_NbSegmentsDlgLayout->setMargin( 11 ); + + /***************************************************************/ + iconLabel = new QLabel( this ); + iconLabel->setPixmap( image0 ); + iconLabel->setScaledContents( false ); + iconLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); + typeLabel = new QLabel( this ); + typeLabel->setText( tr( "SMESH_NB_SEGMENTS_HYPOTHESIS" ) ); + StdMeshersGUI_NbSegmentsDlgLayout->addWidget( iconLabel, 0, 0 ); + StdMeshersGUI_NbSegmentsDlgLayout->addWidget( typeLabel, 0, 1 ); + + /***************************************************************/ + GroupC1 = new QGroupBox( this, "GroupC1" ); + GroupC1->setTitle( tr( "SMESH_ARGUMENTS" ) ); + GroupC1->setColumnLayout(0, Qt::Vertical ); + GroupC1->layout()->setSpacing( 0 ); + GroupC1->layout()->setMargin( 0 ); + QGridLayout* GroupC1Layout = new QGridLayout( GroupC1->layout() ); + GroupC1Layout->setAlignment( Qt::AlignTop ); + GroupC1Layout->setSpacing( 6 ); + GroupC1Layout->setMargin( 11 ); + + LineEdit_NameHypothesis = new QLineEdit( GroupC1, "LineEdit_NameHypothesis" ); + GroupC1Layout->addWidget( LineEdit_NameHypothesis, 0, 1 ); + + TextLabel_NameHypothesis = new QLabel( GroupC1, "TextLabel_NameHypothesis" ); + TextLabel_NameHypothesis->setText( tr( "SMESH_NAME" ) ); + GroupC1Layout->addWidget( TextLabel_NameHypothesis, 0, 0 ); + + TextLabel_NbSeg = new QLabel(GroupC1 , "TextLabel_NbSeg" ); + TextLabel_NbSeg->setText( tr( "SMESH_SEGMENTS" ) ); + GroupC1Layout->addWidget( TextLabel_NbSeg, 1, 0 ); + + SpinBox_NbSeg = new QSpinBox( GroupC1, "SpinBox_NbSeg" ); + GroupC1Layout->addWidget( SpinBox_NbSeg, 1, 1 ); + + StdMeshersGUI_NbSegmentsDlgLayout->addMultiCellWidget(GroupC1 , 1, 1, 0, 1 ); + + /***************************************************************/ + GroupButtons = new QGroupBox( this, "GroupButtons" ); + GroupButtons->setColumnLayout(0, Qt::Vertical ); + GroupButtons->layout()->setSpacing( 0 ); + GroupButtons->layout()->setMargin( 0 ); + QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() ); + GroupButtonsLayout->setAlignment( Qt::AlignTop ); + GroupButtonsLayout->setSpacing( 6 ); + GroupButtonsLayout->setMargin( 11 ); + buttonOk = new QPushButton( GroupButtons, "buttonOk" ); + buttonOk->setText( tr( "SMESH_BUT_OK" ) ); + buttonOk->setAutoDefault( TRUE ); + buttonOk->setDefault( TRUE ); + GroupButtonsLayout->addWidget( buttonOk, 0, 0 ); + buttonApply = new QPushButton( GroupButtons, "buttonApply" ); + buttonApply->setText( tr( "SMESH_BUT_APPLY" ) ); + buttonApply->setAutoDefault( TRUE ); + GroupButtonsLayout->addWidget( buttonApply, 0, 1 ); + QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); + GroupButtonsLayout->addItem( spacer, 0, 2 ); + buttonCancel = new QPushButton( GroupButtons, "buttonCancel" ); + buttonCancel->setText( tr( "SMESH_BUT_CLOSE" ) ); + buttonCancel->setAutoDefault( TRUE ); + GroupButtonsLayout->addWidget( buttonCancel, 0, 3 ); + StdMeshersGUI_NbSegmentsDlgLayout->addMultiCellWidget( GroupButtons, 2, 2, 0, 1 ); + + /***************************************************************/ + Init() ; +} + + +//================================================================================= +// function : ~StdMeshersGUI_NbSegmentsDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +StdMeshersGUI_NbSegmentsDlg::~StdMeshersGUI_NbSegmentsDlg() +{ + // no need to delete child widgets, Qt does it all for us +} + + +//================================================================================= +// function : Init() +// purpose : +//================================================================================= +void StdMeshersGUI_NbSegmentsDlg::Init() +{ + SpinBox_NbSeg->setMinValue( 1 ); + SpinBox_NbSeg->setMaxValue( 9999 ); + SpinBox_NbSeg->setValue(3) ; /* myNbSeg */ + + mySMESHGUI = SMESHGUI::GetSMESHGUI() ; + + char* sHypType = (char*)myHypType.latin1(); + HypothesisData* aHypData = mySMESHGUI->GetHypothesisData(sHypType); + LineEdit_NameHypothesis->setText( aHypData ? aHypData->Label : "" ); + + mySMESHGUI->SetActiveDialogBox( (QDialog*)this ) ; + + /* signals and slots connections */ + connect( buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk()) ); + connect( buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()) ) ; + connect( buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()) ); + + connect( mySMESHGUI, SIGNAL ( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ; + connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) ) ; + + /* Move widget on the botton right corner of main widget */ + int x, y ; + mySMESHGUI->DefineDlgPosition( this, x, y ) ; + this->move( x, y ) ; + this->show() ; /* displays Dialog */ +} + + +//================================================================================= +// function : ClickOnOk() +// purpose : +//================================================================================= +void StdMeshersGUI_NbSegmentsDlg::ClickOnOk() +{ + if ( this->ClickOnApply() ) + this->ClickOnCancel() ; +} + +//================================================================================= +// function : ClickOnApply() +// purpose : +//================================================================================= +bool StdMeshersGUI_NbSegmentsDlg::ClickOnApply() +{ + QString myHypName = LineEdit_NameHypothesis->text().stripWhiteSpace(); + if ( myHypName.isEmpty() ) { + QAD_MessageBox::warn1( this, tr( "SMESH_WRN_WARNING" ), tr( "SMESH_WRN_EMPTY_NAME" ), tr( "SMESH_BUT_OK" ) ); + return false; + } + + long myNbSeg = SpinBox_NbSeg->value(); + + QAD_WaitCursor wc; + try { + SMESH::SMESH_Hypothesis_var Hyp = SMESH::SMESH_Hypothesis::_narrow + (mySMESHGUI->CreateHypothesis(myHypType, + myHypName, + false)); // isAlgorithm + StdMeshers::StdMeshers_NumberOfSegments_var NbS = + StdMeshers::StdMeshers_NumberOfSegments::_narrow(Hyp); + if (!NbS->_is_nil()) + NbS->SetNumberOfSegments(myNbSeg); + } + catch (const SALOME::SALOME_Exception& S_ex) { + wc.stop(); + QtCatchCorbaException(S_ex); + return false; + } + return true; +} + + +//================================================================================= +// function : ClickOnCancel() +// purpose : +//================================================================================= +void StdMeshersGUI_NbSegmentsDlg::ClickOnCancel() +{ + close(); +} + +//================================================================================= +// function : DeactivateActiveDialog() +// purpose : +//================================================================================= +void StdMeshersGUI_NbSegmentsDlg::DeactivateActiveDialog() +{ + iconLabel->setEnabled(false) ; + typeLabel->setEnabled(false) ; + GroupC1->setEnabled(false) ; + GroupButtons->setEnabled(false) ; +} + + +//================================================================================= +// function : ActivateThisDialog() +// purpose : +//================================================================================= +void StdMeshersGUI_NbSegmentsDlg::ActivateThisDialog() +{ + mySMESHGUI->EmitSignalDeactivateDialog() ; + iconLabel->setEnabled(true) ; + typeLabel->setEnabled(true) ; + GroupC1->setEnabled(true) ; + GroupButtons->setEnabled(true) ; +} + + +//================================================================================= +// function : enterEvent() +// purpose : +//================================================================================= +void StdMeshersGUI_NbSegmentsDlg::enterEvent(QEvent* e) +{ + ActivateThisDialog() ; +} + + +//================================================================================= +// function : closeEvent() +// purpose : +//================================================================================= +void StdMeshersGUI_NbSegmentsDlg::closeEvent( QCloseEvent* e ) +{ + mySMESHGUI->ResetState(); + QDialog::closeEvent( e ); +} diff --git a/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsDlg.h b/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsDlg.h new file mode 100644 index 000000000..3594ac960 --- /dev/null +++ b/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsDlg.h @@ -0,0 +1,89 @@ +// SMESH SMESHGUI : GUI for SMESH component +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshersGUI_NbSegmentsDlg.h +// Moved here from SMESHGUI_NbSegmentsDlg.h +// Author : Nicolas REJNERI +// Module : SMESH +// $Header$ + +#ifndef DIALOGBOX_NB_SEGMENTS_H +#define DIALOGBOX_NB_SEGMENTS_H + +// QT Includes +#include + +class QGroupBox; +class QLabel; +class QLineEdit; +class QSpinBox; +class QPushButton; +class SMESHGUI; + +//================================================================================= +// class : StdMeshersGUI_NbSegmentsDlg +// purpose : +//================================================================================= +class StdMeshersGUI_NbSegmentsDlg : public QDialog +{ + Q_OBJECT + +public: + StdMeshersGUI_NbSegmentsDlg (const QString& hypType, + QWidget* parent = 0, + const char* name = 0, + bool modal = FALSE, + WFlags fl = 0); + ~StdMeshersGUI_NbSegmentsDlg (); + +private: + + void Init() ; + void closeEvent( QCloseEvent* e ) ; + void enterEvent ( QEvent * ) ; + + SMESHGUI* mySMESHGUI ; + QString myHypType ; + + QLabel* iconLabel; + QLabel* typeLabel; + QGroupBox* GroupC1; + QLabel* TextLabel_NameHypothesis ; + QLineEdit* LineEdit_NameHypothesis ; + QLabel* TextLabel_NbSeg ; + QSpinBox* SpinBox_NbSeg ; + QGroupBox* GroupButtons; + QPushButton* buttonApply; + QPushButton* buttonOk; + QPushButton* buttonCancel; + +private slots: + + void ClickOnOk(); + void ClickOnCancel(); + bool ClickOnApply(); + void DeactivateActiveDialog() ; + void ActivateThisDialog() ; +}; + +#endif // DIALOGBOX_NB_SEGMENTS_H diff --git a/src/StdMeshersGUI/StdMeshers_icons.po b/src/StdMeshersGUI/StdMeshers_icons.po new file mode 100644 index 000000000..c021365cd --- /dev/null +++ b/src/StdMeshersGUI/StdMeshers_icons.po @@ -0,0 +1,81 @@ +# This is a Qt message file in .po format. Each msgid starts with +# a scope. This scope should *NOT* be translated - eg. "Foo::Bar" +# would be translated to "Pub", not "Foo::Pub". +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2002-05-28 10:57:43 AM CEST\n" +"PO-Revision-Date: YYYY-MM-DD\n" +"Last-Translator: FULLNAME \n" +"Content-Type: text/plain; charset=iso-8859-1\n" + + +#Select Icon +msgid "ICON_SELECT" +msgstr "select1.png" + + +#----------------------------------------------------------- +# Hypothesis +#----------------------------------------------------------- + +#Hypo Local Length +msgid "ICON_DLG_LOCAL_LENGTH" +msgstr "mesh_hypo_length.png" + +#Hypo Nb Segments +msgid "ICON_DLG_NB_SEGMENTS" +msgstr "mesh_hypo_segment.png" + +#Hypo Max Area +msgid "ICON_DLG_MAX_ELEMENT_AREA" +msgstr "mesh_hypo_area.png" + +#Hypo Max Volume +msgid "ICON_DLG_MAX_ELEMENT_VOLUME" +msgstr "mesh_hypo_volume.png" + + +#----------------------------------------------------------- +# ObjectBrowser +#----------------------------------------------------------- + +#mesh_tree_algo_regular +msgid "ICON_SMESH_TREE_ALGO_Regular_1D" +msgstr "mesh_tree_algo_regular.png" + +#mesh_tree_algo_hexa +msgid "ICON_SMESH_TREE_ALGO_Hexa_3D" +msgstr "mesh_tree_algo_hexa.png" + +#mesh_tree_algo_mefisto +msgid "ICON_SMESH_TREE_ALGO_MEFISTO_2D" +msgstr "mesh_tree_algo_mefisto.png" + +#mesh_tree_algo_quad +msgid "ICON_SMESH_TREE_ALGO_Quadrangle_2D" +msgstr "mesh_tree_algo_quad.png" + +#mesh_tree_hypo_area +msgid "ICON_SMESH_TREE_HYPO_MaxElementArea" +msgstr "mesh_tree_hypo_area.png" + +#mesh_tree_hypo_length +msgid "ICON_SMESH_TREE_HYPO_LocalLength" +msgstr "mesh_tree_hypo_length.png" + +#mesh_tree_hypo_segment +msgid "ICON_SMESH_TREE_HYPO_NumberOfSegments" +msgstr "mesh_tree_hypo_segment.png" + +#mesh_tree_hypo_volume +msgid "ICON_SMESH_TREE_HYPO_MaxElementVolume" +msgstr "mesh_tree_hypo_volume.png" + +#mesh_tree_hypo_length +msgid "ICON_SMESH_TREE_HYPO_LengthFromEdges" +msgstr "mesh_tree_hypo_length.png" + +#mesh_tree_hypo_nonconform +msgid "ICON_SMESH_TREE_HYPO_NotConformAllowed" +msgstr "mesh_tree_hypo_length.png" diff --git a/src/StdMeshersGUI/StdMeshers_msg_en.po b/src/StdMeshersGUI/StdMeshers_msg_en.po new file mode 100644 index 000000000..cc6173b71 --- /dev/null +++ b/src/StdMeshersGUI/StdMeshers_msg_en.po @@ -0,0 +1,49 @@ +# This is a Qt message file in .po format. Each msgid starts with +# a scope. This scope should *NOT* be translated - eg. "Foo::Bar" +# would be translated to "Pub", not "Foo::Pub". +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2002-05-28 10:46:48 AM CEST\n" +"PO-Revision-Date: YYYY-MM-DD\n" +"Last-Translator: FULLNAME \n" +"Content-Type: text/plain; charset=iso-8859-1\n" + + +# -------------- Local Length -------------- + +msgid "SMESH_LOCAL_LENGTH_HYPOTHESIS" +msgstr "Local Length" + +msgid "SMESH_LOCAL_LENGTH_TITLE" +msgstr "Hypothesis Construction" + +# ----------- Number of Segments ----------- + +msgid "SMESH_NB_SEGMENTS_HYPOTHESIS" +msgstr "Number of Segments" + +msgid "SMESH_NB_SEGMENTS_TITLE" +msgstr "Hypothesis Construction" + +# ----------- Max. Element Area ------------ + +msgid "SMESH_MAX_ELEMENT_AREA" +msgstr "Max. Area" + +msgid "SMESH_MAX_ELEMENT_AREA_HYPOTHESIS" +msgstr "Max. Element Area" + +msgid "SMESH_MAX_ELEMENT_AREA_TITLE" +msgstr "Hypothesis Construction" + +# ---------- Max. Element Volume ----------- + +msgid "SMESH_MAX_ELEMENT_VOLUME" +msgstr "Max. Volume" + +msgid "SMESH_MAX_ELEMENT_VOLUME_HYPOTHESIS" +msgstr "Max. Element Volume" + +msgid "SMESH_MAX_ELEMENT_VOLUME_TITLE" +msgstr "Hypothesis Construction" diff --git a/src/StdMeshers_I/Makefile.in b/src/StdMeshers_I/Makefile.in new file mode 100644 index 000000000..5891f6e80 --- /dev/null +++ b/src/StdMeshers_I/Makefile.in @@ -0,0 +1,76 @@ +# SMESH StdMeshers_I : idl implementation based on 'StdMeshersPlugin' unit's classes +# +# Copyright (C) 2003 CEA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +# +# +# +# File : Makefile.in +# Author : Julia DOROVSKIKH +# Module : SMESH +# $Header$ + +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl + + +@COMMENCE@ + +# EXPORT_PYSCRIPTS = smeshpy.py SMESH_test.py + +# Libraries targets + +LIB= libStdMeshersEngine.la + +LIB_SRC = \ + StdMeshers_i.cxx \ + StdMeshers_LocalLength_i.cxx \ + StdMeshers_LengthFromEdges_i.cxx \ + StdMeshers_MaxElementArea_i.cxx \ + StdMeshers_MaxElementVolume_i.cxx \ + StdMeshers_NumberOfSegments_i.cxx \ + StdMeshers_NotConformAllowed_i.cxx \ + StdMeshers_Regular_1D_i.cxx \ + StdMeshers_Quadrangle_2D_i.cxx \ + StdMeshers_MEFISTO_2D_i.cxx \ + StdMeshers_Hexa_3D_i.cxx + +LIB_SERVER_IDL = SMESH_BasicHypothesis.idl + +LIB_CLIENT_IDL = \ + SALOMEDS.idl SALOME_Exception.idl \ + GEOM_Gen.idl GEOM_Shape.idl MED.idl SALOMEDS_Attributes.idl \ + SMESH_Gen.idl SMESH_Hypothesis.idl SMESH_Group.idl + +# Executables targets +BIN = +BIN_SRC = + +# additionnal information to compil and link file +CPPFLAGS+= $(OCC_INCLUDES) $(HDF5_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome \ + -I${GEOM_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS) +CXXFLAGS+= $(OCC_CXXFLAGS) $(HDF5_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome + +#IDLCXXFLAGS+= -Wbtp + +#LDFLAGS+= $(HDF5_LIBS) -lStdMeshers -lSMESHEngine -lSalomeLifeCycleCORBA -L${KERNEL_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome -lSalomeGenericObj +LDFLAGS+= $(HDF5_LIBS) -lStdMeshers -lSMESHEngine -L${KERNEL_ROOT_DIR}/lib/salome + +@CONCLUDE@ diff --git a/src/SMESH_I/SMESH_Hexa_3D_i.cxx b/src/StdMeshers_I/StdMeshers_Hexa_3D_i.cxx similarity index 62% rename from src/SMESH_I/SMESH_Hexa_3D_i.cxx rename to src/StdMeshers_I/StdMeshers_Hexa_3D_i.cxx index 1100e6ee6..0ca4839ba 100644 --- a/src/SMESH_I/SMESH_Hexa_3D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_Hexa_3D_i.cxx @@ -21,60 +21,64 @@ // // // -// File : SMESH_Hexa_3D_i.cxx +// File : StdMeshers_Hexa_3D_i.cxx +// Moved here from SMESH_Hexa_3D_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH // $Header$ using namespace std; -using namespace std; -#include "SMESH_Hexa_3D_i.hxx" +#include "StdMeshers_Hexa_3D_i.hxx" #include "SMESH_Gen.hxx" -#include "SMESH_HypothesisFactory.hxx" #include "Utils_CorbaException.hxx" #include "utilities.h" //============================================================================= /*! - * + * StdMeshers_Hexa_3D_i::StdMeshers_Hexa_3D_i + * + * Constructor */ //============================================================================= -SMESH_Hexa_3D_i::SMESH_Hexa_3D_i(const char* anHyp, - int studyId, - ::SMESH_Gen* genImpl) +StdMeshers_Hexa_3D_i::StdMeshers_Hexa_3D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + SMESH_Algo_i( thePOA ), + SMESH_3D_Algo_i( thePOA ) { - MESSAGE("SMESH_Hexa_3D_i::SMESH_Hexa_3D_i"); - _genImpl = genImpl; - ::SMESH_Hexa_3D* impl - = new ::SMESH_Hexa_3D(_genImpl->_hypothesisFactory.GetANewId(), - studyId, - genImpl); - SetImpl(impl); - _baseImpl = _impl; + MESSAGE( "StdMeshers_Hexa_3D_i::StdMeshers_Hexa_3D_i" ); + myBaseImpl = new ::StdMeshers_Hexa_3D( theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); } //============================================================================= /*! - * + * StdMeshers_Hexa_3D_i::~StdMeshers_Hexa_3D_i + * + * Destructor */ //============================================================================= -SMESH_Hexa_3D_i::~SMESH_Hexa_3D_i() +StdMeshers_Hexa_3D_i::~StdMeshers_Hexa_3D_i() { - MESSAGE("SMESH_Hexa_3D_i::~SMESH_Hexa_3D_i"); + MESSAGE( "StdMeshers_Hexa_3D_i::~StdMeshers_Hexa_3D_i" ); } //============================================================================= /*! - * + * StdMeshers_Hexa_3D_i::GetImpl + * + * Get implementation */ //============================================================================= -void SMESH_Hexa_3D_i::SetImpl(::SMESH_Hexa_3D* impl) +::StdMeshers_Hexa_3D* StdMeshers_Hexa_3D_i::GetImpl() { - MESSAGE("SMESH_Hexa_3D_i::SetImpl"); - SMESH_3D_Algo_i::SetImpl(impl); - _impl = impl; + MESSAGE( "StdMeshers_Hexa_3D_i::GetImpl" ); + return ( ::StdMeshers_Hexa_3D* )myBaseImpl; } diff --git a/src/SMESH_I/SMESH_Hexa_3D_i.hxx b/src/StdMeshers_I/StdMeshers_Hexa_3D_i.hxx similarity index 65% rename from src/SMESH_I/SMESH_Hexa_3D_i.hxx rename to src/StdMeshers_I/StdMeshers_Hexa_3D_i.hxx index 19c88b084..91bcabdb8 100644 --- a/src/SMESH_I/SMESH_Hexa_3D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_Hexa_3D_i.hxx @@ -21,7 +21,8 @@ // // // -// File : SMESH_Hexa_3D_i.hxx +// File : StdMeshers_Hexa_3D_i.hxx +// Moved here from SMESH_Hexa_3D_i.hxx // Author : Paul RASCLE, EDF // Module : SMESH // $Header$ @@ -33,24 +34,28 @@ #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) #include "SMESH_3D_Algo_i.hxx" +#include "StdMeshers_Hexa_3D.hxx" -#include "SMESH_Hexa_3D.hxx" +class SMESH_Gen; -class SMESH_Hexa_3D_i: - public POA_SMESH::SMESH_Hexa_3D, - public SMESH_3D_Algo_i +// ====================================================== +// Hexaedron 3d algorithm +// ====================================================== +class StdMeshers_Hexa_3D_i: + public virtual POA_StdMeshers::StdMeshers_Hexa_3D, + public virtual SMESH_3D_Algo_i { public: - SMESH_Hexa_3D_i(const char* anHyp, - int studyId, - ::SMESH_Gen* genImpl); + // Constructor + StdMeshers_Hexa_3D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); - virtual ~SMESH_Hexa_3D_i(); + // Destructor + virtual ~StdMeshers_Hexa_3D_i(); -protected: - virtual void SetImpl(::SMESH_Hexa_3D* impl); - - ::SMESH_Hexa_3D* _impl; + // Get implementation + ::StdMeshers_Hexa_3D* GetImpl(); }; #endif diff --git a/src/SMESH_I/SMESH_LengthFromEdges_i.cxx b/src/StdMeshers_I/StdMeshers_LengthFromEdges_i.cxx similarity index 50% rename from src/SMESH_I/SMESH_LengthFromEdges_i.cxx rename to src/StdMeshers_I/StdMeshers_LengthFromEdges_i.cxx index 1ab700fd2..afcd3b14b 100644 --- a/src/SMESH_I/SMESH_LengthFromEdges_i.cxx +++ b/src/StdMeshers_I/StdMeshers_LengthFromEdges_i.cxx @@ -21,78 +21,101 @@ // // // -// File : SMESH_LengthFromEdges_i.cxx +// File : StdMeshers_LengthFromEdges_i.cxx +// Moved here from SMESH_LengthFromEdges_i.cxx // Author : Nadir BOUHAMOU CEA/DEN, Paul RASCLE, EDF // Module : SMESH // $Header$ using namespace std; -using namespace std; -#include "SMESH_LengthFromEdges_i.hxx" +#include "StdMeshers_LengthFromEdges_i.hxx" #include "SMESH_Gen.hxx" -#include "SMESH_HypothesisFactory.hxx" #include "Utils_CorbaException.hxx" #include "utilities.h" //============================================================================= /*! - * Constructor: - * _name is related to the class name: prefix = SMESH_ ; suffix = _i . + * StdMeshers_LengthFromEdges_i::StdMeshers_LengthFromEdges_i + * + * Constructor */ //============================================================================= -SMESH_LengthFromEdges_i::SMESH_LengthFromEdges_i(const char* anHyp, - int studyId, - ::SMESH_Gen* genImpl) +StdMeshers_LengthFromEdges_i::StdMeshers_LengthFromEdges_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ) { - MESSAGE("SMESH_LengthFromEdges_i::SMESH_LengthFromEdges_i"); - _impl = new ::SMESH_LengthFromEdges(genImpl->_hypothesisFactory.GetANewId(), - studyId, - genImpl); - _baseImpl = _impl; + MESSAGE( "StdMeshers_LengthFromEdges_i::StdMeshers_LengthFromEdges_i" ); + myBaseImpl = new ::StdMeshers_LengthFromEdges( theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); } //============================================================================= /*! - * + * StdMeshers_LengthFromEdges_i::~StdMeshers_LengthFromEdges_i + * + * Destructor */ //============================================================================= -SMESH_LengthFromEdges_i::~SMESH_LengthFromEdges_i() +StdMeshers_LengthFromEdges_i::~StdMeshers_LengthFromEdges_i() { + MESSAGE( "StdMeshers_LengthFromEdges_i::~StdMeshers_LengthFromEdges_i" ); } //============================================================================= /*! - * + * StdMeshers_LengthFromEdges_i::SetMode + * + * Set mode */ //============================================================================= -void SMESH_LengthFromEdges_i::SetMode(CORBA::Long mode) +void StdMeshers_LengthFromEdges_i::SetMode( CORBA::Long theMode ) throw (SALOME::SALOME_Exception) { - ASSERT(_impl); - try - { - _impl->SetMode(mode); - } - catch (SALOME_Exception& S_ex) - { - THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), \ - SALOME::BAD_PARAM); - } + MESSAGE( "StdMeshers_LengthFromEdges_i::SetMode" ); + ASSERT( myBaseImpl ); + try { + this->GetImpl()->SetMode( theMode ); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } +} + +//============================================================================= +/*! + * StdMeshers_LengthFromEdges_i::GetMode + * + * Get mode + */ +//============================================================================= + +CORBA::Long StdMeshers_LengthFromEdges_i::GetMode() +{ + MESSAGE( "StdMeshers_LengthFromEdges_i::GetMode" ); + ASSERT( myBaseImpl ); + return this->GetImpl()->GetMode(); } + //============================================================================= /*! - * + * StdMeshers_LengthFromEdges_i::GetImpl + * + * Get implementation */ //============================================================================= -CORBA::Long SMESH_LengthFromEdges_i::GetMode() +::StdMeshers_LengthFromEdges* StdMeshers_LengthFromEdges_i::GetImpl() { - ASSERT(_impl); - return _impl->GetMode(); + MESSAGE( "StdMeshers_LengthFromEdges_i::GetImpl" ); + return ( ::StdMeshers_LengthFromEdges* )myBaseImpl; } diff --git a/src/SMESH_I/SMESH_LengthFromEdges_i.hxx b/src/StdMeshers_I/StdMeshers_LengthFromEdges_i.hxx similarity index 60% rename from src/SMESH_I/SMESH_LengthFromEdges_i.hxx rename to src/StdMeshers_I/StdMeshers_LengthFromEdges_i.hxx index d773fa0a5..2c988a1f0 100644 --- a/src/SMESH_I/SMESH_LengthFromEdges_i.hxx +++ b/src/StdMeshers_I/StdMeshers_LengthFromEdges_i.hxx @@ -21,7 +21,8 @@ // // // -// File : SMESH_LengthFromEdges_i.hxx +// File : StdMeshers_LengthFromEdges_i.hxx +// Moved here from SMESH_LengthFromEdges_i.hxx // Author : Nadir BOUHAMOU CEA/DEN, Paul RASCLE, EDF // Module : SMESH // $Header$ @@ -33,26 +34,31 @@ #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) #include "SMESH_Hypothesis_i.hxx" +#include "StdMeshers_LengthFromEdges.hxx" -#include "SMESH_LengthFromEdges.hxx" - -class SMESH_LengthFromEdges_i: - public POA_SMESH::SMESH_LengthFromEdges, - public SMESH_Hypothesis_i +// ====================================================== +// Length from edges hypothesis +// ====================================================== +class StdMeshers_LengthFromEdges_i: + public virtual POA_StdMeshers::StdMeshers_LengthFromEdges, + public virtual SMESH_Hypothesis_i { public: - SMESH_LengthFromEdges_i(const char* anHyp, - int studyId, - ::SMESH_Gen* genImpl); - virtual ~SMESH_LengthFromEdges_i(); - - void SetMode(CORBA::Long mode) - throw (SALOME::SALOME_Exception); + // Constructor + StdMeshers_LengthFromEdges_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_LengthFromEdges_i(); + // Set mode + void SetMode( CORBA::Long theMode ) + throw ( SALOME::SALOME_Exception ); + // Get mode CORBA::Long GetMode(); -protected: - ::SMESH_LengthFromEdges* _impl; + // Get implementation + ::StdMeshers_LengthFromEdges* GetImpl(); }; #endif diff --git a/src/SMESH_I/SMESH_MaxElementVolume_i.cxx b/src/StdMeshers_I/StdMeshers_LocalLength_i.cxx similarity index 50% rename from src/SMESH_I/SMESH_MaxElementVolume_i.cxx rename to src/StdMeshers_I/StdMeshers_LocalLength_i.cxx index 9ed53a08d..15b3eb79f 100644 --- a/src/SMESH_I/SMESH_MaxElementVolume_i.cxx +++ b/src/StdMeshers_I/StdMeshers_LocalLength_i.cxx @@ -21,79 +21,99 @@ // // // -// File : SMESH_MaxElementVolume_i.cxx +// File : StdMeshers_LocalLength_i.cxx +// Moved here from SMESH_LocalLength_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH // $Header$ using namespace std; - -#include "SMESH_MaxElementVolume_i.hxx" +#include "StdMeshers_LocalLength_i.hxx" #include "SMESH_Gen.hxx" -#include "SMESH_HypothesisFactory.hxx" #include "Utils_CorbaException.hxx" #include "utilities.h" //============================================================================= /*! - * Constructor: - * _name is related to the class name: prefix = SMESH_ ; suffix = _i . + * StdMeshers_LocalLength_i::StdMeshers_LocalLength_i + * + * Constructor */ //============================================================================= -SMESH_MaxElementVolume_i::SMESH_MaxElementVolume_i(const char* anHyp, - int studyId, - ::SMESH_Gen* genImpl) +StdMeshers_LocalLength_i::StdMeshers_LocalLength_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ) { - MESSAGE("SMESH_MaxElementVolume_i::SMESH_MaxElementVolume_i"); - _impl = new ::SMESH_MaxElementVolume(genImpl->_hypothesisFactory.GetANewId(), - studyId, - genImpl); - _baseImpl = _impl; + MESSAGE( "StdMeshers_LocalLength_i::StdMeshers_LocalLength_i" ); + myBaseImpl = new ::StdMeshers_LocalLength( theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); } //============================================================================= /*! - * + * StdMeshers_LocalLength_i::~StdMeshers_LocalLength_i + * + * Destructor */ //============================================================================= -SMESH_MaxElementVolume_i::~SMESH_MaxElementVolume_i() +StdMeshers_LocalLength_i::~StdMeshers_LocalLength_i() { - MESSAGE("SMESH_MaxElementVolume_i::~SMESH_MaxElementVolume_i()"); + MESSAGE( "StdMeshers_LocalLength_i::~StdMeshers_LocalLength_i" ); } //============================================================================= /*! - * + * StdMeshers_LocalLength_i::SetLength + * + * Set length */ //============================================================================= -void SMESH_MaxElementVolume_i::SetMaxElementVolume(CORBA::Double volume) - throw (SALOME::SALOME_Exception) +void StdMeshers_LocalLength_i::SetLength( CORBA::Double theLength ) + throw ( SALOME::SALOME_Exception ) { - ASSERT(_impl); - try - { - _impl->SetMaxVolume(volume); - } - catch (SALOME_Exception& S_ex) - { - THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), \ - SALOME::BAD_PARAM); - } + MESSAGE( "StdMeshers_LocalLength_i::SetLength" ); + ASSERT( myBaseImpl ); + try { + this->GetImpl()->SetLength( theLength ); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } } //============================================================================= /*! - * + * StdMeshers_LocalLength_i::GetLength + * + * Get length */ //============================================================================= -CORBA::Double SMESH_MaxElementVolume_i::GetMaxElementVolume() +CORBA::Double StdMeshers_LocalLength_i::GetLength() { - ASSERT(_impl); - return _impl->GetMaxVolume(); + MESSAGE( "StdMeshers_LocalLength_i::GetLength" ); + ASSERT( myBaseImpl ); + return this->GetImpl()->GetLength(); } +//============================================================================= +/*! + * StdMeshers_LocalLength_i::GetImpl + * + * Get implementation + */ +//============================================================================= + +::StdMeshers_LocalLength* StdMeshers_LocalLength_i::GetImpl() +{ + MESSAGE( "StdMeshers_LocalLength_i::GetImpl" ); + return ( ::StdMeshers_LocalLength* )myBaseImpl; +} diff --git a/src/StdMeshers_I/StdMeshers_LocalLength_i.hxx b/src/StdMeshers_I/StdMeshers_LocalLength_i.hxx new file mode 100644 index 000000000..6b0b1dbf2 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_LocalLength_i.hxx @@ -0,0 +1,67 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_LocalLength_i.hxx +// Moved here from SMESH_LocalLength_i.hxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +#ifndef _SMESH_LOCALLENGTH_I_HXX_ +#define _SMESH_LOCALLENGTH_I_HXX_ + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_Hypothesis_i.hxx" +#include "StdMeshers_LocalLength.hxx" + +class SMESH_Gen; + +// ====================================================== +// Local Length hypothesis +// ====================================================== +class StdMeshers_LocalLength_i: + public virtual POA_StdMeshers::StdMeshers_LocalLength, + public virtual SMESH_Hypothesis_i +{ +public: + // Constructor + StdMeshers_LocalLength_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_LocalLength_i(); + + // Set length + void SetLength( CORBA::Double theLength ) + throw ( SALOME::SALOME_Exception ); + // Get length + CORBA::Double GetLength(); + + // Get implementation + ::StdMeshers_LocalLength* GetImpl(); +}; + +#endif + diff --git a/src/SMESH_I/SMESH_Quadrangle_2D_i.cxx b/src/StdMeshers_I/StdMeshers_MEFISTO_2D_i.cxx similarity index 60% rename from src/SMESH_I/SMESH_Quadrangle_2D_i.cxx rename to src/StdMeshers_I/StdMeshers_MEFISTO_2D_i.cxx index 73b5728d5..efcc37c5c 100644 --- a/src/SMESH_I/SMESH_Quadrangle_2D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_MEFISTO_2D_i.cxx @@ -21,60 +21,65 @@ // // // -// File : SMESH_Quadrangle_2D_i.cxx +// File : StdMeshers_MEFISTO_2D_i.cxx +// Moved here from SMESH_MEFISTO_2D_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH // $Header$ using namespace std; -using namespace std; -#include "SMESH_Quadrangle_2D_i.hxx" +#include "StdMeshers_MEFISTO_2D_i.hxx" #include "SMESH_Gen.hxx" -#include "SMESH_HypothesisFactory.hxx" #include "Utils_CorbaException.hxx" #include "utilities.h" //============================================================================= /*! - * + * StdMeshers_MEFISTO_2D_i::StdMeshers_MEFISTO_2D_i + * + * Constructor */ //============================================================================= -SMESH_Quadrangle_2D_i::SMESH_Quadrangle_2D_i(const char* anHyp, - int studyId, - ::SMESH_Gen* genImpl) +StdMeshers_MEFISTO_2D_i::StdMeshers_MEFISTO_2D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + SMESH_Algo_i( thePOA ), + SMESH_2D_Algo_i( thePOA ) { - MESSAGE("SMESH_Quadrangle_2D_i::SMESH_Quadrangle_2D_i"); - _genImpl = genImpl; - ::SMESH_Quadrangle_2D* impl - = new ::SMESH_Quadrangle_2D(_genImpl->_hypothesisFactory.GetANewId(), - studyId, - genImpl); - SetImpl(impl); - _baseImpl = _impl; + MESSAGE( "StdMeshers_MEFISTO_2D_i::StdMeshers_MEFISTO_2D_i" ); + myBaseImpl = new ::StdMeshers_MEFISTO_2D( theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); } //============================================================================= /*! - * + * StdMeshers_MEFISTO_2D_i::~StdMeshers_MEFISTO_2D_i + * + * Destructor */ //============================================================================= -SMESH_Quadrangle_2D_i::~SMESH_Quadrangle_2D_i() +StdMeshers_MEFISTO_2D_i::~StdMeshers_MEFISTO_2D_i() { - MESSAGE("SMESH_Quadrangle_2D_i::~SMESH_Quadrangle_2D_i"); + MESSAGE( "StdMeshers_MEFISTO_2D_i::~StdMeshers_MEFISTO_2D_i" ); } //============================================================================= /*! - * + * StdMeshers_MEFISTO_2D_i::GetImpl + * + * Get implementation */ //============================================================================= -void SMESH_Quadrangle_2D_i::SetImpl(::SMESH_Quadrangle_2D* impl) +::StdMeshers_MEFISTO_2D* StdMeshers_MEFISTO_2D_i::GetImpl() { - MESSAGE("SMESH_Quadrangle_2D_i::SetImpl"); - SMESH_2D_Algo_i::SetImpl(impl); - _impl = impl; + MESSAGE( "StdMeshers_MEFISTO_2D_i::GetImpl" ); + return ( ::StdMeshers_MEFISTO_2D* )myBaseImpl; } + diff --git a/src/SMESH_I/SMESH_MEFISTO_2D_i.hxx b/src/StdMeshers_I/StdMeshers_MEFISTO_2D_i.hxx similarity index 60% rename from src/SMESH_I/SMESH_MEFISTO_2D_i.hxx rename to src/StdMeshers_I/StdMeshers_MEFISTO_2D_i.hxx index f60e1305c..d7021df8a 100644 --- a/src/SMESH_I/SMESH_MEFISTO_2D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_MEFISTO_2D_i.hxx @@ -21,36 +21,41 @@ // // // -// File : SMESH_MEFISTO_2D_i.hxx +// File : StdMeshers_MEFISTO_2D_i.hxx +// Moved here from SMESH_MEFISTO_2D_i.hxx // Author : Paul RASCLE, EDF // Module : SMESH // $Header$ -#ifndef _SMESH_MEFISTO_2D_I_HXX_ -#define _SMESH_MEFISTO_2D_I_HXX_ +#ifndef _StdMeshers_MEFISTO_2D_I_HXX_ +#define _StdMeshers_MEFISTO_2D_I_HXX_ #include #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) #include "SMESH_2D_Algo_i.hxx" +#include "StdMeshers_MEFISTO_2D.hxx" -#include "SMESH_MEFISTO_2D.hxx" +class SMESH_Gen; -class SMESH_MEFISTO_2D_i: - public POA_SMESH::SMESH_MEFISTO_2D, - public SMESH_2D_Algo_i +// ====================================================== +// Triangle (MEFISTO) 2d algorithm +// ====================================================== +class StdMeshers_MEFISTO_2D_i: + public virtual POA_StdMeshers::StdMeshers_MEFISTO_2D, + public virtual SMESH_2D_Algo_i { public: - SMESH_MEFISTO_2D_i(const char* anHyp, - int studyId, - ::SMESH_Gen* genImpl); + // Constructor + StdMeshers_MEFISTO_2D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); - virtual ~SMESH_MEFISTO_2D_i(); + // Destructor + virtual ~StdMeshers_MEFISTO_2D_i(); -protected: - virtual void SetImpl(::SMESH_MEFISTO_2D* impl); - - ::SMESH_MEFISTO_2D* _impl; + // Get implementation + ::StdMeshers_MEFISTO_2D* GetImpl(); }; #endif diff --git a/src/StdMeshers_I/StdMeshers_MaxElementArea_i.cxx b/src/StdMeshers_I/StdMeshers_MaxElementArea_i.cxx new file mode 100644 index 000000000..51810e0a7 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_MaxElementArea_i.cxx @@ -0,0 +1,119 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_MaxElementArea_i.cxx +// Moved here from SMESH_MaxElementArea_i.cxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +using namespace std; +#include "StdMeshers_MaxElementArea_i.hxx" +#include "SMESH_Gen.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +//============================================================================= +/*! + * StdMeshers_MaxElementArea_i::StdMeshers_MaxElementArea_i + * + * Constructor + */ +//============================================================================= + +StdMeshers_MaxElementArea_i::StdMeshers_MaxElementArea_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ) +{ + MESSAGE( "StdMeshers_MaxElementArea_i::StdMeshers_MaxElementArea_i" ); + myBaseImpl = new ::StdMeshers_MaxElementArea( theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); +} + +//============================================================================= +/*! + * StdMeshers_MaxElementArea_i::~StdMeshers_MaxElementArea_i + * + * Destructor + */ +//============================================================================= + +StdMeshers_MaxElementArea_i::~StdMeshers_MaxElementArea_i() +{ + MESSAGE( "StdMeshers_MaxElementArea_i::~StdMeshers_MaxElementArea_i" ); +} + +//============================================================================= +/*! + * StdMeshers_MaxElementArea_i::SetMaxElementArea + * + * Set maximum element area + */ +//============================================================================= + +void StdMeshers_MaxElementArea_i::SetMaxElementArea( CORBA::Double theArea ) + throw ( SALOME::SALOME_Exception ) +{ + MESSAGE( "StdMeshers_MaxElementArea_i::SetMaxElementArea" ); + ASSERT( myBaseImpl ); + try { + this->GetImpl()->SetMaxArea( theArea ); + } + catch (SALOME_Exception& S_ex) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } +} + +//============================================================================= +/*! + * StdMeshers_MaxElementArea_i::GetMaxElementArea + * + * Get maximum element area + */ +//============================================================================= + +CORBA::Double StdMeshers_MaxElementArea_i::GetMaxElementArea() +{ + MESSAGE( "StdMeshers_MaxElementArea_i::GetMaxElementArea" ); + ASSERT( myBaseImpl ); + return this->GetImpl()->GetMaxArea(); +} + +//============================================================================= +/*! + * StdMeshers_MaxElementArea_i::GetImpl + * + * Get implementation + */ +//============================================================================= + +::StdMeshers_MaxElementArea* StdMeshers_MaxElementArea_i::GetImpl() +{ + MESSAGE( "StdMeshers_MaxElementArea_i::GetImpl" ); + return ( ::StdMeshers_MaxElementArea* )myBaseImpl; +} diff --git a/src/SMESH_I/SMESH_MaxElementArea_i.hxx b/src/StdMeshers_I/StdMeshers_MaxElementArea_i.hxx similarity index 60% rename from src/SMESH_I/SMESH_MaxElementArea_i.hxx rename to src/StdMeshers_I/StdMeshers_MaxElementArea_i.hxx index 3195b4e4c..da21f809c 100644 --- a/src/SMESH_I/SMESH_MaxElementArea_i.hxx +++ b/src/StdMeshers_I/StdMeshers_MaxElementArea_i.hxx @@ -21,7 +21,8 @@ // // // -// File : SMESH_MaxElementArea_i.hxx +// File : StdMeshers_MaxElementArea_i.hxx +// Moved here from SMESH_MaxElementArea_i.hxx // Author : Paul RASCLE, EDF // Module : SMESH // $Header$ @@ -33,26 +34,31 @@ #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) #include "SMESH_Hypothesis_i.hxx" +#include "StdMeshers_MaxElementArea.hxx" -#include "SMESH_MaxElementArea.hxx" - -class SMESH_MaxElementArea_i: - public POA_SMESH::SMESH_MaxElementArea, - public SMESH_Hypothesis_i +// ====================================================== +// Maximum Element Area hypothesis +// ====================================================== +class StdMeshers_MaxElementArea_i: + public virtual POA_StdMeshers::StdMeshers_MaxElementArea, + public virtual SMESH_Hypothesis_i { public: - SMESH_MaxElementArea_i(const char* anHyp, - int studyId, - ::SMESH_Gen* genImpl); - virtual ~SMESH_MaxElementArea_i(); - - void SetMaxElementArea(CORBA::Double area) - throw (SALOME::SALOME_Exception); + // Constructor + StdMeshers_MaxElementArea_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_MaxElementArea_i(); + // Set maximum element area + void SetMaxElementArea( CORBA::Double theArea ) + throw ( SALOME::SALOME_Exception ); + // Get maximum element area CORBA::Double GetMaxElementArea(); -protected: - ::SMESH_MaxElementArea* _impl; + // Get implementation + ::StdMeshers_MaxElementArea* GetImpl(); }; #endif diff --git a/src/StdMeshers_I/StdMeshers_MaxElementVolume_i.cxx b/src/StdMeshers_I/StdMeshers_MaxElementVolume_i.cxx new file mode 100644 index 000000000..eb071b664 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_MaxElementVolume_i.cxx @@ -0,0 +1,120 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_MaxElementVolume_i.cxx +// Moved here from SMESH_MaxElementVolume_i.cxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +using namespace std; +#include "StdMeshers_MaxElementVolume_i.hxx" +#include "SMESH_Gen.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +//============================================================================= +/*! + * StdMeshers_MaxElementVolume_i::StdMeshers_MaxElementVolume_i + * + * Constructor + */ +//============================================================================= + +StdMeshers_MaxElementVolume_i::StdMeshers_MaxElementVolume_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ) +{ + MESSAGE( "StdMeshers_MaxElementVolume_i::StdMeshers_MaxElementVolume_i" ); + myBaseImpl = new ::StdMeshers_MaxElementVolume( theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); +} + +//============================================================================= +/*! + * StdMeshers_MaxElementVolume_i::~StdMeshers_MaxElementVolume_i + * + * Destructor + */ +//============================================================================= + +StdMeshers_MaxElementVolume_i::~StdMeshers_MaxElementVolume_i() +{ + MESSAGE( "StdMeshers_MaxElementVolume_i::~StdMeshers_MaxElementVolume_i()" ); +} + +//============================================================================= +/*! + * StdMeshers_MaxElementVolume_i::SetMaxElementVolume + * + * Set maximum element volume + */ +//============================================================================= + +void StdMeshers_MaxElementVolume_i::SetMaxElementVolume( CORBA::Double theVolume ) + throw ( SALOME::SALOME_Exception ) +{ + MESSAGE( "StdMeshers_MaxElementVolume_i::SetMaxElementVolume" ); + ASSERT( myBaseImpl ); + try { + this->GetImpl()->SetMaxVolume( theVolume ); + } + catch (SALOME_Exception& S_ex) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } +} + +//============================================================================= +/*! + * StdMeshers_MaxElementVolume_i::GetMaxElementVolume + * + * Get maximum element volume + */ +//============================================================================= + +CORBA::Double StdMeshers_MaxElementVolume_i::GetMaxElementVolume() +{ + MESSAGE( "StdMeshers_MaxElementVolume_i::GetMaxElementVolume" ); + ASSERT( myBaseImpl ); + return this->GetImpl()->GetMaxVolume(); +} + +//============================================================================= +/*! + * StdMeshers_MaxElementVolume_i::GetImpl + * + * Get implementation + */ +//============================================================================= + +::StdMeshers_MaxElementVolume* StdMeshers_MaxElementVolume_i::GetImpl() +{ + MESSAGE( "StdMeshers_MaxElementVolume_i::GetImpl" ); + return ( ::StdMeshers_MaxElementVolume* )myBaseImpl; +} + diff --git a/src/SMESH_I/SMESH_MaxElementVolume_i.hxx b/src/StdMeshers_I/StdMeshers_MaxElementVolume_i.hxx similarity index 60% rename from src/SMESH_I/SMESH_MaxElementVolume_i.hxx rename to src/StdMeshers_I/StdMeshers_MaxElementVolume_i.hxx index c59fd65b1..328b4af87 100644 --- a/src/SMESH_I/SMESH_MaxElementVolume_i.hxx +++ b/src/StdMeshers_I/StdMeshers_MaxElementVolume_i.hxx @@ -21,7 +21,8 @@ // // // -// File : SMESH_MaxElementVolume_i.hxx +// File : StdMeshers_MaxElementVolume_i.hxx +// Moved here from SMESH_MaxElementVolume_i.hxx // Author : Paul RASCLE, EDF // Module : SMESH // $Header$ @@ -33,26 +34,31 @@ #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) #include "SMESH_Hypothesis_i.hxx" +#include "StdMeshers_MaxElementVolume.hxx" -#include "SMESH_MaxElementVolume.hxx" - -class SMESH_MaxElementVolume_i: - public POA_SMESH::SMESH_MaxElementVolume, - public SMESH_Hypothesis_i +// ====================================================== +// Maximum Element Volume hypothesis +// ====================================================== +class StdMeshers_MaxElementVolume_i: + public virtual POA_StdMeshers::StdMeshers_MaxElementVolume, + public virtual SMESH_Hypothesis_i { public: - SMESH_MaxElementVolume_i(const char* anHyp, - int studyId, - ::SMESH_Gen* genImpl); - virtual ~SMESH_MaxElementVolume_i(); + // Constructor + StdMeshers_MaxElementVolume_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_MaxElementVolume_i(); - void SetMaxElementVolume(CORBA::Double volume) + // Set maximum element volume + void SetMaxElementVolume( CORBA::Double theVolume ) throw (SALOME::SALOME_Exception); - + // Get maximum element volume CORBA::Double GetMaxElementVolume(); -protected: - ::SMESH_MaxElementVolume* _impl; + // Get implementation + ::StdMeshers_MaxElementVolume* GetImpl(); }; #endif diff --git a/src/SMESH_I/SMESH_Regular_1D_i.cxx b/src/StdMeshers_I/StdMeshers_NotConformAllowed_i.cxx similarity index 58% rename from src/SMESH_I/SMESH_Regular_1D_i.cxx rename to src/StdMeshers_I/StdMeshers_NotConformAllowed_i.cxx index bd8e1b1d5..e2fad1e67 100644 --- a/src/SMESH_I/SMESH_Regular_1D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_NotConformAllowed_i.cxx @@ -1,4 +1,4 @@ -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// SMESH StdMeshers_I : idl implementation based on 'SMESH' unit's classes // // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -21,49 +21,36 @@ // // // -// File : SMESH_Regular_1D_i.cxx +// File : StdMeshers_NotConformAllowed_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH // $Header$ using namespace std; using namespace std; -#include "SMESH_Regular_1D_i.hxx" +#include "StdMeshers_NotConformAllowed_i.hxx" #include "SMESH_Gen.hxx" -#include "SMESH_HypothesisFactory.hxx" -#include "Utils_CorbaException.hxx" #include "utilities.h" //============================================================================= /*! - * - */ -//============================================================================= - -SMESH_Regular_1D_i::SMESH_Regular_1D_i(const char* anHyp, - int studyId, - ::SMESH_Gen* genImpl) -{ - MESSAGE("SMESH_Regular_1D_i::SMESH_Regular_1D_i"); - _genImpl = genImpl; - ::SMESH_Regular_1D* impl - = new ::SMESH_Regular_1D(_genImpl->_hypothesisFactory.GetANewId(), - studyId, - genImpl); - SetImpl(impl); - _baseImpl = _impl; -} - -//============================================================================= -/*! - * + * Constructor: + * _name is related to the class name: prefix = SMESH_ ; suffix = _i . */ //============================================================================= -SMESH_Regular_1D_i::~SMESH_Regular_1D_i() +StdMeshers_NotConformAllowed_i::StdMeshers_NotConformAllowed_i + (PortableServer::POA_ptr thePOA, + int studyId, + ::SMESH_Gen* genImpl) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ) { - MESSAGE("SMESH_Regular_1D_i::~SMESH_Regular_1D_i"); + MESSAGE("StdMeshers_NotConformAllowed_i::StdMeshers_NotConformAllowed_i"); + myBaseImpl = new ::StdMeshers_NotConformAllowed(genImpl->GetANewId(), + studyId, + genImpl); } //============================================================================= @@ -72,9 +59,6 @@ SMESH_Regular_1D_i::~SMESH_Regular_1D_i() */ //============================================================================= -void SMESH_Regular_1D_i::SetImpl(::SMESH_Regular_1D* impl) +StdMeshers_NotConformAllowed_i::~StdMeshers_NotConformAllowed_i() { - MESSAGE("SMESH_Regular_1D_i::SetImpl"); - SMESH_1D_Algo_i::SetImpl(impl); - _impl = impl; } diff --git a/src/SMESH_I/SMESH_LocalLength_i.hxx b/src/StdMeshers_I/StdMeshers_NotConformAllowed_i.hxx similarity index 66% rename from src/SMESH_I/SMESH_LocalLength_i.hxx rename to src/StdMeshers_I/StdMeshers_NotConformAllowed_i.hxx index 18803a762..a9151d34c 100644 --- a/src/SMESH_I/SMESH_LocalLength_i.hxx +++ b/src/StdMeshers_I/StdMeshers_NotConformAllowed_i.hxx @@ -1,4 +1,4 @@ -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// SMESH StdMeshers_I : idl implementation based on 'SMESH' unit's classes // // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -21,38 +21,33 @@ // // // -// File : SMESH_LocalLength_i.hxx +// File : StdMeshers_NotConformAllowed_i.hxx // Author : Paul RASCLE, EDF // Module : SMESH // $Header$ -#ifndef _SMESH_LOCALLENGTH_I_HXX_ -#define _SMESH_LOCALLENGTH_I_HXX_ +#ifndef _StdMeshers_NotConformAllowed_I_HXX_ +#define _StdMeshers_NotConformAllowed_I_HXX_ #include #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) #include "SMESH_Hypothesis_i.hxx" -#include "SMESH_LocalLength.hxx" +#include "StdMeshers_NotConformAllowed.hxx" -class SMESH_LocalLength_i: - public POA_SMESH::SMESH_LocalLength, +class StdMeshers_NotConformAllowed_i: + public POA_StdMeshers::StdMeshers_NotConformAllowed, public SMESH_Hypothesis_i { public: - SMESH_LocalLength_i(const char* anHyp, - int studyId, - ::SMESH_Gen* genImpl); - virtual ~SMESH_LocalLength_i(); - - void SetLength(CORBA::Double length) - throw (SALOME::SALOME_Exception); - - CORBA::Double GetLength(); + StdMeshers_NotConformAllowed_i(PortableServer::POA_ptr thePOA, + int studyId, + ::SMESH_Gen* genImpl); + virtual ~StdMeshers_NotConformAllowed_i(); protected: - ::SMESH_LocalLength* _impl; + ::StdMeshers_NotConformAllowed* _impl; }; #endif diff --git a/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.cxx b/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.cxx new file mode 100644 index 000000000..bf326bdf3 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.cxx @@ -0,0 +1,157 @@ +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_NumberOfSegments_i.cxx +// Moved here from SMESH_NumberOfSegments_i.cxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// $Header$ + +using namespace std; +#include "StdMeshers_NumberOfSegments_i.hxx" +#include "SMESH_Gen.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +//============================================================================= +/*! + * StdMeshers_NumberOfSegments_i::StdMeshers_NumberOfSegments_i + * + * Constructor + */ +//============================================================================= + +StdMeshers_NumberOfSegments_i::StdMeshers_NumberOfSegments_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ) +{ + MESSAGE( "StdMeshers_NumberOfSegments_i::StdMeshers_NumberOfSegments_i" ); + myBaseImpl = new ::StdMeshers_NumberOfSegments( theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); +} + +//============================================================================= +/*! + * StdMeshers_NumberOfSegments_i::~StdMeshers_NumberOfSegments_i + * + * Destructor + */ +//============================================================================= + +StdMeshers_NumberOfSegments_i::~StdMeshers_NumberOfSegments_i() +{ + MESSAGE( "StdMeshers_NumberOfSegments_i::~StdMeshers_NumberOfSegments_i" ); +} + +//============================================================================= +/*! + * StdMeshers_NumberOfSegments_i::SetNumberOfSegments + * + * Set number of segments + */ +//============================================================================= + +void StdMeshers_NumberOfSegments_i::SetNumberOfSegments( CORBA::Long theSegmentsNumber ) + throw ( SALOME::SALOME_Exception ) +{ + MESSAGE( "StdMeshers_NumberOfSegments_i::SetNumberOfSegments" ); + ASSERT( myBaseImpl ); + try { + this->GetImpl()->SetNumberOfSegments( theSegmentsNumber ); + } + catch (SALOME_Exception& S_ex) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } +} + +//============================================================================= +/*! + * StdMeshers_NumberOfSegments_i::GetNumberOfSegments + * + * Get number of segments + */ +//============================================================================= + +CORBA::Long StdMeshers_NumberOfSegments_i::GetNumberOfSegments() +{ + MESSAGE( "StdMeshers_NumberOfSegments_i::GetNumberOfSegments" ); + ASSERT( myBaseImpl ); + return this->GetImpl()->GetNumberOfSegments(); +} + +//============================================================================= +/*! + * StdMeshers_NumberOfSegments_i::SetScaleFactor + * + * Set scalar factor + */ +//============================================================================= + +void StdMeshers_NumberOfSegments_i::SetScaleFactor( CORBA::Double theScaleFactor ) + throw ( SALOME::SALOME_Exception ) +{ + MESSAGE( "StdMeshers_NumberOfSegments_i::SetScaleFactor" ); + ASSERT( myBaseImpl ); + try { + this->GetImpl()->SetScaleFactor( theScaleFactor ); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } +} + +//============================================================================= +/*! + * StdMeshers_NumberOfSegments_i::GetScaleFactor + * + * Get scalar factor + */ +//============================================================================= + +CORBA::Double StdMeshers_NumberOfSegments_i::GetScaleFactor() +{ + MESSAGE( "StdMeshers_NumberOfSegments_i::GetScaleFactor" ); + ASSERT( myBaseImpl ); + return this->GetImpl()->GetScaleFactor(); +} + +//============================================================================= +/*! + * StdMeshers_NumberOfSegments_i::GetImpl + * + * Get implementation + */ +//============================================================================= + +::StdMeshers_NumberOfSegments* StdMeshers_NumberOfSegments_i::GetImpl() +{ + MESSAGE( "StdMeshers_NumberOfSegments_i::GetImpl" ); + return ( ::StdMeshers_NumberOfSegments* )myBaseImpl; +} + diff --git a/src/SMESH_I/SMESH_NumberOfSegments_i.hxx b/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.hxx similarity index 56% rename from src/SMESH_I/SMESH_NumberOfSegments_i.hxx rename to src/StdMeshers_I/StdMeshers_NumberOfSegments_i.hxx index 85482fa57..e8a5030b1 100644 --- a/src/SMESH_I/SMESH_NumberOfSegments_i.hxx +++ b/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.hxx @@ -21,7 +21,8 @@ // // // -// File : SMESH_NumberOfSegments_i.hxx +// File : StdMeshers_NumberOfSegments_i.hxx +// Moved here from SMESH_NumberOfSegments_i.hxx // Author : Paul RASCLE, EDF // Module : SMESH // $Header$ @@ -33,31 +34,37 @@ #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) #include "SMESH_Hypothesis_i.hxx" +#include "StdMeshers_NumberOfSegments.hxx" -#include "SMESH_NumberOfSegments.hxx" - -class SMESH_NumberOfSegments_i: - public POA_SMESH::SMESH_NumberOfSegments, - public SMESH_Hypothesis_i +// ====================================================== +// Number of segments hypothesis +// ====================================================== +class StdMeshers_NumberOfSegments_i: + public virtual POA_StdMeshers::StdMeshers_NumberOfSegments, + public virtual SMESH_Hypothesis_i { public: - SMESH_NumberOfSegments_i(const char* anHyp, - int studyId, - ::SMESH_Gen* genImpl); - virtual ~SMESH_NumberOfSegments_i(); - - void SetNumberOfSegments(CORBA::Long segmentsNumber) - throw (SALOME::SALOME_Exception); + // Constructor + StdMeshers_NumberOfSegments_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_NumberOfSegments_i(); + // Set number of segments + void SetNumberOfSegments( CORBA::Long theSegmentsNumber ) + throw ( SALOME::SALOME_Exception ); + // Get number of segments CORBA::Long GetNumberOfSegments(); - void SetScaleFactor(CORBA::Double scaleFactor) - throw (SALOME::SALOME_Exception); - + // Set scalar factor + void SetScaleFactor( CORBA::Double theScaleFactor ) + throw ( SALOME::SALOME_Exception ); + // Get scalar factor CORBA::Double GetScaleFactor(); -protected: - ::SMESH_NumberOfSegments* _impl; + // Get implementation + ::StdMeshers_NumberOfSegments* GetImpl(); }; #endif diff --git a/src/SMESH_I/SMESH_MEFISTO_2D_i.cxx b/src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.cxx similarity index 59% rename from src/SMESH_I/SMESH_MEFISTO_2D_i.cxx rename to src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.cxx index ceac666a2..059eac91f 100644 --- a/src/SMESH_I/SMESH_MEFISTO_2D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.cxx @@ -21,60 +21,66 @@ // // // -// File : SMESH_MEFISTO_2D_i.cxx +// File : StdMeshers_Quadrangle_2D_i.cxx +// Moved here from SMESH_Quadrangle_2D_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH // $Header$ using namespace std; -using namespace std; -#include "SMESH_MEFISTO_2D_i.hxx" +#include "StdMeshers_Quadrangle_2D_i.hxx" #include "SMESH_Gen.hxx" -#include "SMESH_HypothesisFactory.hxx" #include "Utils_CorbaException.hxx" #include "utilities.h" //============================================================================= /*! - * + * StdMeshers_Quadrangle_2D_i::StdMeshers_Quadrangle_2D_i + * + * Constructor */ //============================================================================= -SMESH_MEFISTO_2D_i::SMESH_MEFISTO_2D_i(const char* anHyp, - int studyId, - ::SMESH_Gen* genImpl) +StdMeshers_Quadrangle_2D_i::StdMeshers_Quadrangle_2D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + SMESH_Algo_i( thePOA ), + SMESH_2D_Algo_i( thePOA ) { - MESSAGE("SMESH_MEFISTO_2D_i::SMESH_MEFISTO_2D_i"); - _genImpl = genImpl; - ::SMESH_MEFISTO_2D* impl - = new ::SMESH_MEFISTO_2D(_genImpl->_hypothesisFactory.GetANewId(), - studyId, - genImpl); - SetImpl(impl); - _baseImpl = _impl; + MESSAGE( "StdMeshers_Quadrangle_2D_i::StdMeshers_Quadrangle_2D_i" ); + myBaseImpl = new ::StdMeshers_Quadrangle_2D( theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); } //============================================================================= /*! + * StdMeshers_Quadrangle_2D_i::~StdMeshers_Quadrangle_2D_i + * + * Destructor * */ //============================================================================= -SMESH_MEFISTO_2D_i::~SMESH_MEFISTO_2D_i() +StdMeshers_Quadrangle_2D_i::~StdMeshers_Quadrangle_2D_i() { - MESSAGE("SMESH_MEFISTO_2D_i::~SMESH_MEFISTO_2D_i"); + MESSAGE( "StdMeshers_Quadrangle_2D_i::~StdMeshers_Quadrangle_2D_i" ); } //============================================================================= /*! - * + * StdMeshers_Quadrangle_2D_i::GetImpl + * + * Get implementation */ //============================================================================= -void SMESH_MEFISTO_2D_i::SetImpl(::SMESH_MEFISTO_2D* impl) +::StdMeshers_Quadrangle_2D* StdMeshers_Quadrangle_2D_i::GetImpl() { - MESSAGE("SMESH_MEFISTO_2D_i::SetImpl"); - SMESH_2D_Algo_i::SetImpl(impl); - _impl = impl; + MESSAGE( "StdMeshers_Quadrangle_2D_i::GetImpl" ); + return ( ::StdMeshers_Quadrangle_2D* )myBaseImpl; } + diff --git a/src/SMESH_I/SMESH_Quadrangle_2D_i.hxx b/src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.hxx similarity index 63% rename from src/SMESH_I/SMESH_Quadrangle_2D_i.hxx rename to src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.hxx index c68fc0c1a..a8c1e281f 100644 --- a/src/SMESH_I/SMESH_Quadrangle_2D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.hxx @@ -21,7 +21,8 @@ // // // -// File : SMESH_Quadrangle_2D_i.hxx +// File : StdMeshers_Quadrangle_2D_i.hxx +// Moved here from SMESH_Quadrangle_2D_i.hxx // Author : Paul RASCLE, EDF // Module : SMESH // $Header$ @@ -33,24 +34,28 @@ #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) #include "SMESH_2D_Algo_i.hxx" +#include "StdMeshers_Quadrangle_2D.hxx" -#include "SMESH_Quadrangle_2D.hxx" +class SMESH_Gen; -class SMESH_Quadrangle_2D_i: - public POA_SMESH::SMESH_Quadrangle_2D, - public SMESH_2D_Algo_i +// ====================================================== +// Quadrangle (Mapping) 2d algorithm +// ====================================================== +class StdMeshers_Quadrangle_2D_i: + public virtual POA_StdMeshers::StdMeshers_Quadrangle_2D, + public virtual SMESH_2D_Algo_i { public: - SMESH_Quadrangle_2D_i(const char* anHyp, - int studyId, - ::SMESH_Gen* genImpl); + // Constructor + StdMeshers_Quadrangle_2D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); - virtual ~SMESH_Quadrangle_2D_i(); + // Destructor + virtual ~StdMeshers_Quadrangle_2D_i(); -protected: - virtual void SetImpl(::SMESH_Quadrangle_2D* impl); - - ::SMESH_Quadrangle_2D* _impl; + // Get implementation + ::StdMeshers_Quadrangle_2D* GetImpl(); }; #endif diff --git a/src/SMESH_I/SMESH_LocalLength_i.cxx b/src/StdMeshers_I/StdMeshers_Regular_1D_i.cxx similarity index 60% rename from src/SMESH_I/SMESH_LocalLength_i.cxx rename to src/StdMeshers_I/StdMeshers_Regular_1D_i.cxx index 9dfccf119..24f322c58 100644 --- a/src/SMESH_I/SMESH_LocalLength_i.cxx +++ b/src/StdMeshers_I/StdMeshers_Regular_1D_i.cxx @@ -21,78 +21,65 @@ // // // -// File : SMESH_LocalLength_i.cxx +// File : StdMeshers_Regular_1D_i.cxx +// Moved here from SMESH_Regular_1D_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH // $Header$ using namespace std; -using namespace std; -#include "SMESH_LocalLength_i.hxx" +#include "StdMeshers_Regular_1D_i.hxx" #include "SMESH_Gen.hxx" -#include "SMESH_HypothesisFactory.hxx" #include "Utils_CorbaException.hxx" #include "utilities.h" //============================================================================= /*! - * Constructor: - * _name is related to the class name: prefix = SMESH_ ; suffix = _i . - */ -//============================================================================= - -SMESH_LocalLength_i::SMESH_LocalLength_i(const char* anHyp, - int studyId, - ::SMESH_Gen* genImpl) -{ - MESSAGE("SMESH_LocalLength_i::SMESH_LocalLength_i"); - _impl = new ::SMESH_LocalLength(genImpl->_hypothesisFactory.GetANewId(), - studyId, - genImpl); - _baseImpl = _impl; -} - -//============================================================================= -/*! - * + * StdMeshers_Regular_1D_i::StdMeshers_Regular_1D_i + * + * Constructor */ //============================================================================= -SMESH_LocalLength_i::~SMESH_LocalLength_i() +StdMeshers_Regular_1D_i::StdMeshers_Regular_1D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + SMESH_Algo_i( thePOA ), + SMESH_1D_Algo_i( thePOA ) { + MESSAGE( "StdMeshers_Regular_1D_i::StdMeshers_Regular_1D_i" ); + myBaseImpl = new ::StdMeshers_Regular_1D( theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); } //============================================================================= /*! - * + * StdMeshers_Regular_1D_i::~StdMeshers_Regular_1D_i + * + * Destructor */ //============================================================================= -void SMESH_LocalLength_i::SetLength(CORBA::Double length) - throw (SALOME::SALOME_Exception) +StdMeshers_Regular_1D_i::~StdMeshers_Regular_1D_i() { - ASSERT(_impl); - try - { - _impl->SetLength(length); - } - catch (SALOME_Exception& S_ex) - { - THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), \ - SALOME::BAD_PARAM); - } + MESSAGE( "StdMeshers_Regular_1D_i::~StdMeshers_Regular_1D_i" ); } //============================================================================= /*! - * + * StdMeshers_Regular_1D_i::GetImpl + * + * Get implementation */ //============================================================================= -CORBA::Double SMESH_LocalLength_i::GetLength() +::StdMeshers_Regular_1D* StdMeshers_Regular_1D_i::GetImpl() { - ASSERT(_impl); - return _impl->GetLength(); + MESSAGE( "StdMeshers_Regular_1D_i::GetImpl" ); + return ( ::StdMeshers_Regular_1D* )myBaseImpl; } diff --git a/src/SMESH_I/SMESH_Regular_1D_i.hxx b/src/StdMeshers_I/StdMeshers_Regular_1D_i.hxx similarity index 64% rename from src/SMESH_I/SMESH_Regular_1D_i.hxx rename to src/StdMeshers_I/StdMeshers_Regular_1D_i.hxx index e1a58a0b9..3231532fd 100644 --- a/src/SMESH_I/SMESH_Regular_1D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_Regular_1D_i.hxx @@ -21,7 +21,8 @@ // // // -// File : SMESH_Regular_1D_i.hxx +// File : StdMeshers_Regular_1D_i.hxx +// Moved here from SMESH_Regular_1D_i.hxx // Author : Paul RASCLE, EDF // Module : SMESH // $Header$ @@ -33,24 +34,25 @@ #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) #include "SMESH_1D_Algo_i.hxx" - -#include "SMESH_Regular_1D.hxx" - -class SMESH_Regular_1D_i: - public POA_SMESH::SMESH_Regular_1D, - public SMESH_1D_Algo_i +#include "StdMeshers_Regular_1D.hxx" + +// ====================================================== +// Wire Discretization 1d algorithm +// ====================================================== +class StdMeshers_Regular_1D_i: + public virtual POA_StdMeshers::StdMeshers_Regular_1D, + public virtual SMESH_1D_Algo_i { public: - SMESH_Regular_1D_i(const char* anHyp, - int studyId, - ::SMESH_Gen* genImpl); - - virtual ~SMESH_Regular_1D_i(); + // Constructor + StdMeshers_Regular_1D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_Regular_1D_i(); -protected: - virtual void SetImpl(::SMESH_Regular_1D* impl); - - ::SMESH_Regular_1D* _impl; + // Get implementation + ::StdMeshers_Regular_1D* GetImpl(); }; #endif diff --git a/src/StdMeshers_I/StdMeshers_i.cxx b/src/StdMeshers_I/StdMeshers_i.cxx new file mode 100644 index 000000000..c24606d6b --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_i.cxx @@ -0,0 +1,86 @@ +// SMESH StdMeshers : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 CEA +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_i.cxx +// Author : Julia DOROVSKIKH +// Module : SMESH +// $Header$ + +using namespace std; +#include "SMESH_Gen_i.hxx" + +#include "utilities.h" + +#include "StdMeshers_LocalLength_i.hxx" +#include "StdMeshers_LengthFromEdges_i.hxx" +#include "StdMeshers_NotConformAllowed_i.hxx" +#include "StdMeshers_NumberOfSegments_i.hxx" +#include "StdMeshers_MaxElementArea_i.hxx" +#include "StdMeshers_MaxElementVolume_i.hxx" + +#include "StdMeshers_Regular_1D_i.hxx" +#include "StdMeshers_MEFISTO_2D_i.hxx" +#include "StdMeshers_Quadrangle_2D_i.hxx" +#include "StdMeshers_Hexa_3D_i.hxx" + +//============================================================================= +/*! + * + */ +//============================================================================= + +extern "C" +{ + GenericHypothesisCreator_i* GetHypothesisCreator (const char* aHypName) + { + MESSAGE("Get HypothesisCreator for " << aHypName); + + GenericHypothesisCreator_i* aCreator = 0; + + // Hypotheses + if (strcmp(aHypName, "LocalLength") == 0) + aCreator = new HypothesisCreator_i; + else if (strcmp(aHypName, "NumberOfSegments") == 0) + aCreator = new HypothesisCreator_i; + else if (strcmp(aHypName, "LengthFromEdges") == 0) + aCreator = new HypothesisCreator_i; + else if (strcmp(aHypName, "NotConformAllowed") == 0) + aCreator = new HypothesisCreator_i; + else if (strcmp(aHypName, "MaxElementArea") == 0) + aCreator = new HypothesisCreator_i; + else if (strcmp(aHypName, "MaxElementVolume") == 0) + aCreator = new HypothesisCreator_i; + + // Algorithms + else if (strcmp(aHypName, "Regular_1D") == 0) + aCreator = new HypothesisCreator_i; + else if (strcmp(aHypName, "MEFISTO_2D") == 0) + aCreator = new HypothesisCreator_i; + else if (strcmp(aHypName, "Quadrangle_2D") == 0) + aCreator = new HypothesisCreator_i; + else if (strcmp(aHypName, "Hexa_3D") == 0) + aCreator = new HypothesisCreator_i; + else ; + + return aCreator; + } +} -- 2.39.2